<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- saved from url=(0052)http://blog.csdn.net/innost/article/details/48228651 -->
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">   
   

    <script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/tracking.js" charset="utf-8"></script>  

    <script type="text/javascript">
        var protocol = window.location.protocol;
        document.write('<script type="text/javascript" src="' + protocol + '//csdnimg.cn/pubfooter/js/repoAddr2.js?v=' + Math.random() + '"></' + 'script>');
    </script><script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/repoAddr2.js"></script>

  
 <meta http-equiv="Cache-Control" content="no-siteapp"><link rel="alternate" media="handheld" href="http://blog.csdn.net/innost/article/details/48228651#">

    <title>深入理解Android之Gradle - Innost的专栏
        - 博客频道 - CSDN.NET</title>
    
    <meta name="description" content="Android 混淆代码总结">
    <script src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/jquery.js" type="text/javascript"></script>
      <script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/jquery-version.js"></script>
    <script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/ad.js"></script>
        <!--new top-->
       
        <link rel="stylesheet" href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/index.css">
        <!--new top-->
    
      <!-- ad begin -->
         <script language="javascript" type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/tracking(1).js"></script>
    <!-- ad end-->

    <link rel="Stylesheet" type="text/css" href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/style.css">
    <link id="RSSLink" title="RSS" type="application/rss+xml" rel="alternate" href="http://blog.csdn.net/Innost/rss/list">
    <link rel="shortcut icon" href="http://c.csdnimg.cn/public/favicon.ico">
    <link type="text/css" rel="stylesheet" href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/default.css">
 


<script src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/share.js"></script><link rel="stylesheet" type="text/css" href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/job_reco.css"><style type="text/css">.MathJax_Hover_Frame {border-radius: .25em; -webkit-border-radius: .25em; -moz-border-radius: .25em; -khtml-border-radius: .25em; box-shadow: 0px 0px 15px #83A; -webkit-box-shadow: 0px 0px 15px #83A; -moz-box-shadow: 0px 0px 15px #83A; -khtml-box-shadow: 0px 0px 15px #83A; border: 1px solid #A6D ! important; display: inline-block; position: absolute}
.MathJax_Hover_Arrow {position: absolute; width: 15px; height: 11px; cursor: pointer}
</style><style type="text/css">#MathJax_About {position: fixed; left: 50%; width: auto; text-align: center; border: 3px outset; padding: 1em 2em; background-color: #DDDDDD; color: black; cursor: default; font-family: message-box; font-size: 120%; font-style: normal; text-indent: 0; text-transform: none; line-height: normal; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; z-index: 201; border-radius: 15px; -webkit-border-radius: 15px; -moz-border-radius: 15px; -khtml-border-radius: 15px; box-shadow: 0px 10px 20px #808080; -webkit-box-shadow: 0px 10px 20px #808080; -moz-box-shadow: 0px 10px 20px #808080; -khtml-box-shadow: 0px 10px 20px #808080; filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}
.MathJax_Menu {position: absolute; background-color: white; color: black; width: auto; padding: 2px; border: 1px solid #CCCCCC; margin: 0; cursor: default; font: menu; text-align: left; text-indent: 0; text-transform: none; line-height: normal; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; z-index: 201; box-shadow: 0px 10px 20px #808080; -webkit-box-shadow: 0px 10px 20px #808080; -moz-box-shadow: 0px 10px 20px #808080; -khtml-box-shadow: 0px 10px 20px #808080; filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}
.MathJax_MenuItem {padding: 2px 2em; background: transparent}
.MathJax_MenuArrow {position: absolute; right: .5em; color: #666666}
.MathJax_MenuActive .MathJax_MenuArrow {color: white}
.MathJax_MenuArrow.RTL {left: .5em; right: auto}
.MathJax_MenuCheck {position: absolute; left: .7em}
.MathJax_MenuCheck.RTL {right: .7em; left: auto}
.MathJax_MenuRadioCheck {position: absolute; left: 1em}
.MathJax_MenuRadioCheck.RTL {right: 1em; left: auto}
.MathJax_MenuLabel {padding: 2px 2em 4px 1.33em; font-style: italic}
.MathJax_MenuRule {border-top: 1px solid #CCCCCC; margin: 4px 1px 0px}
.MathJax_MenuDisabled {color: GrayText}
.MathJax_MenuActive {background-color: Highlight; color: HighlightText}
.MathJax_Menu_Close {position: absolute; width: 31px; height: 31px; top: -15px; left: -15px}
</style><style type="text/css">#MathJax_Zoom {position: absolute; background-color: #F0F0F0; overflow: auto; display: block; z-index: 301; padding: .5em; border: 1px solid black; margin: 0; font-weight: normal; font-style: normal; text-align: left; text-indent: 0; text-transform: none; line-height: normal; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; box-shadow: 5px 5px 15px #AAAAAA; -webkit-box-shadow: 5px 5px 15px #AAAAAA; -moz-box-shadow: 5px 5px 15px #AAAAAA; -khtml-box-shadow: 5px 5px 15px #AAAAAA; filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}
#MathJax_ZoomOverlay {position: absolute; left: 0; top: 0; z-index: 300; display: inline-block; width: 100%; height: 100%; border: 0; padding: 0; margin: 0; background-color: white; opacity: 0; filter: alpha(opacity=0)}
#MathJax_ZoomFrame {position: relative; display: inline-block; height: 0; width: 0}
#MathJax_ZoomEventTrap {position: absolute; left: 0; top: 0; z-index: 302; display: inline-block; border: 0; padding: 0; margin: 0; background-color: white; opacity: 0; filter: alpha(opacity=0)}
</style><style type="text/css">.MathJax_Preview {color: #888}
#MathJax_Message {position: fixed; left: 1em; bottom: 1.5em; background-color: #E6E6E6; border: 1px solid #959595; margin: 0px; padding: 2px 8px; z-index: 102; color: black; font-size: 80%; width: auto; white-space: nowrap}
#MathJax_MSIE_Frame {position: absolute; top: 0; left: 0; width: 0px; z-index: 101; border: 0px; margin: 0px; padding: 0px}
.MathJax_Error {color: #CC0000; font-style: italic}
</style><link rel="stylesheet" type="text/css" href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/style(1).css"><link type="text/css" rel="stylesheet" href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/style(2).css"><script src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/get_ads.php" type="text/javascript"></script><script src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/logger.js"></script><link href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/bdsstyle.css" rel="stylesheet" type="text/css"><link rel="stylesheet" href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/share_style0_16.css"></head>
<body><iframe frameborder="0" style="display: none;" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/saved_resource.html"></iframe><div id="MathJax_Message" style="display: none;"></div>
    <!-- 广告位开始 -->
        <ins data-revive-zoneid="149" data-revive-id="8c38e720de1c90a6f6ff52f3f89c4d57" id="revive-0-0"></ins>
    <!-- 广告位结束 -->

    
   
      <!--new top-->
    <script id="toolbar-tpl-scriptId" fixed="true" prod="blog" skin="black" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/html.js" type="text/javascript"></script><div class="csdn-toolbar csdn-toolbar-skin-black ">        <div class="container row center-block ">          <div class="col-md-3 pull-left logo clearfix"><a href="http://www.csdn.net/?ref=toolbar" title="CSDN首页" target="_blank" class="icon"></a><a title="频道首页" href="http://blog.csdn.net/?ref=toolbar_logo" class="img blog-icon"></a></div>          <div class="pull-right login-wrap unlogin">            <ul class="btns">              <li class="loginlink"><a href="https://passport.csdn.net/account/login?ref=toolbar" target="_top">登录&nbsp;</a>|<a target="_top" href="http://passport.csdn.net/account/mobileregister?ref=toolbar&amp;action=mobileRegister">&nbsp;注册</a></li>              <li class="search">                <div class="icon on-search-icon">                  <div class="wrap">                    <div class="curr-icon-wrap">                      <div class="curr-icon"></div>                    </div>                    <form action="http://so.csdn.net/search" method="get" target="_blank">                      <input type="hidden" value="toolbar" name="ref" accesskey="2">                      <div class="border">                        <input placeholder="搜索" type="text" value="" name="q" accesskey="2"><span class="icon-enter-sm"></span>                      </div>                    </form>                  </div>                </div>              </li>              <li class="favor">                <div class="icon on-favor-icon">                  <div class="wrap">                    <div class="curr-icon-wrap">                      <div class="curr-icon"></div>                    </div>                    <div style="display:none;" class="favor-success"><span class="msg">收藏成功</span>                      <div class="btns"><span class="btn btn-primary ok">确定</span></div>                    </div>                    <div style="display:none;" class="favor-failed"><span class="icon-danger-lg"></span><span class="msg">收藏失败，请重新收藏</span>                      <div class="btns"><span class="btn btn-primary ok">确定</span></div>                    </div>                    <form role="form" class="form-horizontal favor-form">                      <div class="form-group">                        <div class="clearfix">                          <label for="input-title" class="col-sm-2 control-label">标题</label>                          <div class="col-sm-10">                            <input id="inputTitle" type="text" placeholder="" class="title form-control">                          </div>                        </div>                        <div class="alert alert-danger"><strong></strong>标题不能为空</div>                      </div>                      <div class="form-group">                        <label for="input-url" class="col-sm-2 control-label">网址</label>                        <div class="col-sm-10">                          <input id="input-url" type="text" placeholder="" class="url form-control">                        </div>                      </div>                      <div class="form-group">                        <label for="input-tag" class="col-sm-2 tag control-label">标签</label>                        <div class="col-sm-10">                          <input id="input-tag" type="text" class="form-control tag">                        </div>                      </div>                      <div class="form-group">                        <label for="input-description" class="description col-sm-2 control-label">摘要</label>                        <div class="col-sm-10">                          <textarea id="input-description" class="form-control description"></textarea>                        </div>                      </div>                      <div class="form-group">                        <div class="col-sm-offset-2 col-sm-10 ft">                          <div class="col-sm-4 pull-left">                            <div class="checkbox">                              <label>                                <input type="checkbox" name="share" checked="checked" class="share">公开                              </label>                            </div>                          </div>                          <div class="col-sm-8 pull-right favor-btns">                            <button type="button" class="cancel btn btn-default">取消</button>                            <button type="submit" class="submit btn btn-primary">收藏</button>                          </div>                        </div>                      </div>                    </form>                  </div>                </div>              </li>              <li class="notify">                <div style="display:none" class="number"></div>                <div style="display:none" class="icon-hasnotes-sm"></div>                <div id="header_notice_num"></div>                <div class="icon on-notify-icon">                  <div class="wrap">                    <div class="curr-icon-wrap">                      <div class="curr-icon"></div>                    </div>                    <div id="note1" class="csdn_note">                      <div class="box"></div>                    <iframe src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/saved_resource(1).html" frameborder="0" allowtransparency="true" style="z-index:-1;position:absolute;top:0;left:0;width:100%;height:100%;background:transparent"></iframe></div>                  </div>                </div>              </li>              <li class="ugc">                <div class="icon on-ugc-icon">                  <div class="wrap clearfix">                    <div class="curr-icon-wrap">                      <div class="curr-icon"></div>                    </div>                    <dl>                      <dt><a href="http://geek.csdn.net/news/expert?ref=toolbar" target="_blank" class="p-news clearfix" style="display:none;"><em class="icon"></em><span>分享资讯</span></a></dt>                      <dt style="border: none;"><a href="http://u.download.csdn.net/upload?ref=toolbar" target="_blank" class="p-doc clearfix"><em class="icon"></em><span>传PPT/文档</span></a></dt>                      <dt><a href="http://bbs.csdn.net/topics/new?ref=toolbar" target="_blank" class="p-ask clearfix"><em class="icon"></em><span>提问题</span></a></dt>                      <dt><a href="http://write.blog.csdn.net/postedit?ref=toolbar" target="_blank" class="p-blog clearfix"><em class="icon"></em><span>写博客</span></a></dt>                      <dt><a href="http://u.download.csdn.net/upload?ref=toolbar" target="_blank" class="p-src clearfix"><em class="icon"></em><span>传资源</span></a></dt>                      <dt><a href="https://code.csdn.net/projects/new?ref=toolbar" target="_blank" class="c-obj clearfix"><em class="icon"></em><span>创建项目</span></a></dt>                      <dt><a href="https://code.csdn.net/snippets/new?ref=toolbar" target="_blank" class="c-code clearfix"><em class="icon"></em><span>创建代码片</span></a></dt>                    </dl>                  </div>                </div>              </li>              <li class="profile">                <div class="icon on-profile-icon"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/100x100.jpg" class="curr-icon-img">                  <div class="wrap clearfix">                    <div class="curr-icon-wrap">                      <div class="curr-icon"></div>                    </div>                    <div class="bd">                      <dl class="clearfix">                        <dt class="pull-left img"><a target="_blank" href="http://my.csdn.net/?ref=toolbar" class="avatar"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/100x100.jpg"></a></dt>                        <dd class="info" style="border: none;"><a target="_blank" href="http://my.csdn.net/?ref=toolbar" class="nickname"></a><a class="set-nick" href="https://passport.csdn.net/account/profile">设置昵称<span class="write-icon"></span></a><span class="dec"><a class="fill-dec" href="http://my.csdn.net/" target="_blank">编辑自我介绍，让更多人了解你<span class="write-icon"></span></a></span></dd>                      </dl>                    </div>                    <div class="ft clearfix"><a target="_blank" href="http://my.csdn.net/my/account/changepwd?ref=toolbar" class="pull-left"><span class="icon-cog"></span>帐号设置</a><a href="https://passport.csdn.net/account/logout?ref=toolbar" target="_top" class="pull-left" style="margin-left:132px; width:18px; height:27px; white-space:nowrap; overflow:hidden;"><span class="icon-signout"></span><span class="out">退出</span></a></div>                  </div>                </div>              </li>              <li class="apps">                <div id="chasnew123" class="hasnew" style="display: none;"></div>                <div id="cappsarea123" class="icon on-apps-icon">                  <div class="wrap clearfix">                    <div class="curr-icon-wrap">                      <div class="curr-icon"></div>                    </div>                  <div class="detail">                    <dl>                      <dt>                        <h5>社区</h5>                      </dt>                      <dd> <a href="http://blog.csdn.net/?ref=toolbar" target="_blank">博客</a></dd>                      <dd> <a href="http://bbs.csdn.net/?ref=toolbar" target="_blank">论坛</a></dd>                      <dd> <a href="http://download.csdn.net/?ref=toolbar" target="_blank">下载</a></dd>                      <dd> <a href="http://lib.csdn.net/?ref=toolbar" target="_blank">知识库</a></dd>                      <dd><a href="http://ask.csdn.net/?ref=toolbar" target="_blank">技术问答</a></dd>                      <dd><a href="http://geek.csdn.net/?ref=toolbar" target="_blank">极客头条</a></dd>                      <dd style="display:none"> <a href="http://hero.csdn.net/?ref=toolbar" target="_blank">英雄会</a></dd>                    </dl>                  </div>                  <div class="detail">                    <dl>                      <dt>                        <h5>服务</h5>                      </dt>                      <dd style="display:none"> <a href="http://job.csdn.net/?ref=toolbar" target="_blank">JOB<img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/new.gif" style="display: none; margin-top: -26px; width: 23px;"></a></dd>                      <dd> <a href="http://edu.csdn.net/?ref=toolbar" target="_blank">学院<img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/new.gif" style="display: none; margin-top: -26px; width: 23px;"></a></dd>                      <dd> <a href="https://code.csdn.net/?ref=toolbar" target="_blank">CODE</a></dd>                      <dd> <a href="http://huiyi.csdn.net/?ref=toolbar" target="_blank">活动</a></dd>                      <dd> <a href="http://www.csto.com/?ref=toolbar" target="_blank">CSTO</a></dd>                      <dd> <a href="http://mall.csdn.net/?ref=toolbar" target="_blank">C币兑换<img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/new.gif" style="display: none; margin-top: -26px; width: 23px;"></a></dd>                    </dl>                  </div>                  <div class="detail last">                    <dl>                      <dt>                        <h5>俱乐部</h5>                      </dt>                      <dd> <a href="http://cto.csdn.net/?ref=toolbar" target="_blank">CTO俱乐部</a></dd>                      <dd> <a href="http://student.csdn.net/?ref=toolbar" target="_blank">高校俱乐部</a></dd>                    </dl>                  </div>                </div>              </div>            </li>            </ul>          </div>        </div>    </div>
     <!--new top-->
    <div id="container">
        <div id="header">
    <div class="header">
        <div id="blog_title">
            <h2>
                <a href="http://blog.csdn.net/innost">Innost的专栏</a></h2>
            <h3>深入理解Android与其他技术，管理，人生百态，团队建设等</h3>
            <div class="clear">
            </div>
        </div>
        <div class="clear">
        </div>
        
     
    </div>
</div>
<div id="navigator">
    <div class="navigator_bg">
    </div>
    <div class="navigator">
        <ul>
            
                <li id="btnContents"><a href="http://blog.csdn.net/innost?viewmode=contents"><span onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_mulu&#39;])">
                    <img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/ico_list.gif">目录视图</span></a></li>
                <li id="btnView"><a href="http://blog.csdn.net/innost?viewmode=list"><span onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_zhaiyao&#39;])">
                    <img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/ico_summary.gif">摘要视图</span></a></li>
                <li id="btnRss"><a href="http://blog.csdn.net/innost/rss/list"><span onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_RSS&#39;])">
                    <img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/ico_rss.gif">订阅</span></a></li>                
            

            </ul>
    </div>
</div>
<script type="text/javascript">
    var username = "Innost";
    var _blogger = username;
    var blog_address = "http://blog.csdn.net/innost";
    var static_host = "http://static.blog.csdn.net";
    var currentUserName = "";  
</script>

        <div id="body">
            <div id="main">
                <div class="main">
                        <div class="ad_class">
<div class="notice tracking-ad" data-mod="popu_3"> 


<a href="http://blog.csdn.net/blogdevteam/article/details/51919935" target="_blank">
<font color="blue">【公告】博客系统优化升级</font></a>
&nbsp;&nbsp;&nbsp;
<a href="http://lib.csdn.net/base/scala" target="_blank">
<font color="red">【收藏】Scala 资源一应俱全
</font></a>
&nbsp;&nbsp;&nbsp;
<a href="http://blog.csdn.net/blogdevteam/article/details/51984275" target="_blank">
<font color="blue">博乐招募开始啦
</font></a>
&nbsp;&nbsp;&nbsp;

<a href="http://geek.csdn.net/news/detail/94222" target="_blank">
<font color="red">程序员七夕表白礼品指南
</font></a>
&nbsp;&nbsp;&nbsp;


</div>                        </div>
                        



<!-- 广告位开始 -->
<div class="J_adv" data-view="true" data-mod="ad_popu_72" data-mtp="40" data-order="40" data-con="ad_content_217" style="width: 1px; height: 1px; position: fixed; right: 10px; bottom: 10px; z-index: 999; background-color: transparent;"><div id="location_parent"></div><script>document.getElementById('location_parent').parentNode.style.height='1px';document.getElementById('location_parent').parentNode.style.width='1px';document.getElementById('location_parent').parentNode.style.position='fixed';document.getElementById('location_parent').parentNode.style.right='10px';document.getElementById('location_parent').parentNode.style.bottom='10px';document.getElementById('location_parent').parentNode.style.zIndex=999;document.getElementById('location_parent').parentNode.style.backgroundColor='transparent';</script><!-- 广告占位容器 --><div id="cpro_u2392861" style="box-sizing: content-box; width: 311px; height: 286px; overflow: hidden; z-index: 2147483647; position: fixed; bottom: 10px; right: 10px;"><div style="box-sizing: content-box;width:300px;height:250px;padding:4px;border:#acacac 1px solid;overflow:hidden;position:absolute;left:0;top:25px;"><iframe id="cpro_u2392861_iframe" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/ocsm.html" width="300" height="250" align="center,center" vspace="0" hspace="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" style="border:0; vertical-align:bottom;margin:0;" allowtransparency="true"></iframe></div><div id="cpro_u2392861_closebtn" style="box-sizing: content-box;position:absolute;width:61px;height:20px;top:0;left:250px;margin:0;padding:0;margin-bottom:5px;cursor:pointer;overflow:hidden;"><div style="box-sizing: content-box;width:40px;height:20px;background-color:#999999;color:#fff;float:left;margin-right:1px;font-size:12px;font-family:微软雅黑;text-align: center;line-height:20px;">关闭</div><a style="maring:0;padding:0;display:inline-block;border:none;overflow:hidden;height:20px;line-height:20px;cursor:pointer;width:20px;background:url(&#39;//cpro.baidustatic.com/cpro/ui/noexpire/img/2.0.1/xuanfu_close.png&#39;) no-repeat 0 0;margin-bottom:3px;float:left"></a></div></div><!-- 投放代码 --><script type="text/javascript">(window['cproStyleApi'] = window['cproStyleApi'] || {})['u2392861']={at:'3',rsi0:'300',rsi1:'250',pat:'17',tn:'baiduCustNativeAD_xuanfu',rss1:'#FFFFFF',conBW:'1',adp:'1',ptt:'0',titFF:'%E5%BE%AE%E8%BD%AF%E9%9B%85%E9%BB%91',titFS:'14',rss2:'#000000',titSU:'0'};/*服务器频道首页置顶Banner960*90，创建于2014-7-3*/(window.cproArray = window.cproArray || []).push({id:'u2392861'});  </script>  <script src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/f.js" type="text/javascript"></script></div>
<!-- 广告位结束 -->

  
<link href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/comment1.css" type="text/css" rel="stylesheet">
<link href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/style1.css" type="text/css" rel="stylesheet">
<script language="JavaScript" type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/jquery.cookie.js"></script>
<script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/main.js"></script>
<link rel="stylesheet" href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/markdown_views.css">
<link rel="stylesheet" href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/category.css">
<script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/MathJax.js"></script>
<script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/web-storage-cache.min.js"></script>
<script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/replace.min.js"></script>




  <script type="text/ecmascript">
      window.quickReplyflag = true;
           
            var isBole = false;
            
          
    </script>
<div id="article_details" class="details">
    <div class="article_title">   
         <span class="ico ico_type_Original"></span>


    <h1>
        <span class="link_title"><a href="http://blog.csdn.net/innost/article/details/48228651">
        深入理解Android之Gradle            
        </a></span>
    </h1>
</div>

   

        <div class="article_manage clearfix">
        <div class="article_r">
            <span class="link_postdate">2015-09-05 20:07</span>
            <span class="link_view" title="阅读次数">61933人阅读</span>
            <span class="link_comments" title="评论次数"> <a href="http://blog.csdn.net/innost/article/details/48228651#comments" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_pinglun&#39;])">评论</a>(101)</span>
            <span class="link_collect tracking-ad" data-mod="popu_171"> <a href="javascript:void(0);" onclick="javascript:collectArticle(&#39;深入理解Android之Gradle&#39;,&#39;48228651&#39;);return false;" title="收藏" target="_blank">收藏</a></span>
             <span class="link_report"> <a href="http://blog.csdn.net/innost/article/details/48228651#report" onclick="javascript:report(48228651,2);return false;" title="举报">举报</a></span>

        </div>
    </div>
    <div class="embody" style="" id="embody">
        <span class="embody_t">本文章已收录于：</span>
        <div class="embody_c" id="lib" value="{&quot;err&quot;:0,&quot;msg&quot;:&quot;ok&quot;,&quot;data&quot;:[{&quot;name&quot;:&quot;Android知识库&quot;,&quot;url&quot;:&quot;http://lib.csdn.net/base/15?source=blogtop&quot;,&quot;logo&quot;:&quot;http://img.knowledge.csdn.net/upload/base/1455589744328_328.jpg&quot;}]}"> <a href="http://lib.csdn.net/base/15?source=blogtop" target="_blank"> <img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/1455589744328_328.jpg"> <em><b>Android知识库</b></em> </a></div>
    </div>
    <style type="text/css">        
            .embody{
                padding:10px 10px 10px;
                margin:0 -20px;
                border-bottom:solid 1px #ededed;                
            }
            .embody_b{
                margin:0 ;
                padding:10px 0;
            }
            .embody .embody_t,.embody .embody_c{
                display: inline-block;
                margin-right:10px;
            }
            .embody_t{
                font-size: 12px;
                color:#999;
            }
            .embody_c{
                font-size: 12px;
            }
            .embody_c img,.embody_c em{
                display: inline-block;
                vertical-align: middle;               
            }
             .embody_c img{               
                width:30px;
                height:30px;
            }
            .embody_c em{
                margin: 0 20px 0 10px;
                color:#333;
                font-style: normal;
            }
    </style>
    <script type="text/javascript">
        $(function () {
            try
            {
                var lib = eval("("+$("#lib").attr("value")+")");
                var html = "";
                if (lib.err == 0) {
                    $.each(lib.data, function (i) {
                        var obj = lib.data[i];
                        //html += '<img src="' + obj.logo + '"/>' + obj.name + "&nbsp;&nbsp;";
                        html += ' <a href="' + obj.url + '" target="_blank">';
                        html += ' <img src="' + obj.logo + '">';
                        html += ' <em><b>' + obj.name + '</b></em>';
                        html += ' </a>';
                    });
                    if (html != "") {
                        setTimeout(function () {
                            $("#lib").html(html);                      
                            $("#embody").show();
                        }, 100);
                    }
                }      
            } catch (err)
            { }
            
        });
    </script>
      <div class="category clearfix">
        <div class="category_l">
           <img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/category_icon.jpg">
            <span>分类：</span>
        </div>
        <div class="category_r">
                    <label onclick="GetCategoryArticles(&#39;767414&#39;,&#39;Innost&#39;,&#39;top&#39;,&#39;48228651&#39;);">
                        <span onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_fenlei&#39;]);">Android开发系列<em>（106）</em></span>
                      <img class="arrow-down" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/arrow_triangle _down.jpg" style="display:inline;">
                      <img class="arrow-up" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/arrow_triangle_up.jpg" style="display:none;">
                        <div class="subItem">
                            <div class="subItem_t"><a href="http://blog.csdn.net/Innost/article/category/767414" target="_blank">作者同类文章</a><i class="J_close">X</i></div>
                            <ul class="subItem_l" id="top_767414">                            
                            </ul>
                        </div>
                    </label>                    
        </div>
    </div>
    <script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/category.js"></script>  
        <div class="bog_copyright">         
            <p class="copyright_p">版权声明：本文为博主原创文章，未经博主允许不得转载。</p>
        </div>

  

  
  
     

<div style="clear:both"></div><div style="border:solid 1px #ccc; background:#eee; float:left; min-width:200px;padding:4px 10px;"><p style="text-align:right;margin:0;"><span style="float:left;">目录<a href="http://blog.csdn.net/innost/article/details/48228651#" title="系统根据文章中H1到H6标签自动生成文章目录">(?)</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" onclick="javascript:return openct(this);" title="展开">[+]</a></p><ol style="display:none;margin-left:14px;padding-left:14px;line-height:160%;"><li><a href="http://blog.csdn.net/innost/article/details/48228651#t0">深入理解Android之Gradle</a></li><ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t1">一题外话</a></li></ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t2">二闲言构建</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t3">三Groovy介绍</a></li><ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t4">1&nbsp; Groovy开发环境</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t5">2&nbsp; 一些前提知识</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t6">3&nbsp; Groovy中的数据类型</a></li><ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t7">31&nbsp; 基本数据类型</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t8">32&nbsp; 容器类</a></li><ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t9">List类</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t10">Map类</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t11">Range类</a></li></ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t12">34&nbsp; Groovy API的一些秘笈</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t13">4&nbsp; 闭包</a></li><ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t14">41&nbsp; 闭包的样子</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t15">42&nbsp; Closure使用中的注意点</a></li><ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t16">省略圆括号</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t17">如何确定Closure的参数</a></li></ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t18">5&nbsp; 脚本类文件IO和XML操作</a></li><ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t19">51&nbsp; 脚本类</a></li><ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t20">脚本中import其他类</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t21">脚本到底是什么</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t22">脚本中的变量和作用域</a></li></ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t23">52&nbsp; 文件IO操作</a></li><ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t24">读文件</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t25">写文件</a></li></ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t26">53&nbsp; XML操作</a></li></ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t27">6&nbsp; 更多</a></li></ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t28">四Gradle介绍</a></li><ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t29">1&nbsp; Gradle开发环境部署</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t30">2&nbsp; 基本组件</a></li><ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t31">21&nbsp; 一个重要的例子</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t32">22&nbsp; gradle命令介绍</a></li><ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t33">gradle projects查看工程信息</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t34">gradle tasks查看任务信息</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t35">gradle task-name执行任务</a></li></ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t36">3&nbsp; Gradle工作流程</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t37">4&nbsp; Gradle编程模型及API实例详解</a></li><ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t38">41&nbsp; Gradle对象</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t39">42&nbsp; Project对象</a></li><ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t40">加载插件</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t41">设置属性</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t42">Task介绍</a></li></ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t43">43&nbsp; posdevice实例</a></li><ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t44">utilsgradle</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t45">settingsgradle</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t46">posdevicebuildgradle</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t47">CPosDeviceSdkbuildgradle</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t48">CPosDeviceServerApk buildgradle</a></li><li><a href="http://blog.csdn.net/innost/article/details/48228651#t49">结果展示</a></li></ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t50">44&nbsp; 实例2</a></li></ol><li><a href="http://blog.csdn.net/innost/article/details/48228651#t51">五总结</a></li></ol></ol></ol></ol></ol></div><div style="clear:both"></div><div id="article_content" class="article_content">
<h1 style="text-align: center;"><a name="t0"></a>深入理解Android之Gradle</h1><p><span style="font-size:24px;">格式更加精美的PDF版请到：<span style="color:#ff0000;"><strong>http://vdisk.weibo.com/s/z68f8l0xTYrZt </strong></span>下载</span></p><p><span style="font-size:24px;"><br></span></p><p>Gradle是当前非常“劲爆”得构建工具。本篇文章就是专为讲解Gradle而来。介绍Gradle之前，先说点题外话。</p><h4><a name="t1"></a>一、题外话</h4><p>说实话，我在大法工作的时候，就见过Gradle。但是当时我一直不知道这是什么东西。而且大法工具组的工程师还将其和Android Studio大法版一起推送，偶一看就更没兴趣了。为什么那个时候如此不待见Gradle呢？因为我此前一直是做ROM开发。在这个层面上，我们用make，mm或者mmm就可以了。而且，编译耗时对我们来说也不是啥痛点，因为用组内吊炸天的神机服务器完整编译大法的image也要耗费1个小时左右。所以，那个时侯Gradle完全不是我们的菜。</p><p>现在，搞APP开发居多，编译/打包等问题立即就成痛点了。比如：</p><p></p><ul><li>一个APP有多个版本，Release版、Debug版、Test版。甚至针对不同APP Store都有不同的版本。在以前ROM的环境下，虽然可以配置Android.mk，但是需要依赖整个Android源码，而且还不能完全做到满足条件，很多事情需要手动搞。一个app如果涉及到多个开发者，手动操作必然会带来混乱。</li><li>library工程我们需要编译成jar包，然后发布给其他开发者使用。以前是用eclipse的export，做一堆选择。要是能自动编译成jar包就爽了。</li></ul><p></p><p>上述问题对绝大部分APP开发者而言都不陌生，而<em>Gradle</em>作为一种很方便的的构建工具，可以非常轻松得解决构建过程中的各种问题。</p><h2><a name="t2"></a>二、闲言构建</h2><p>构建，叫build也好，叫make也行。反正就是根据输入信息然后干一堆事情，最后得到几个产出物（Artifact）。</p><p>最最简单的构建工具就是make了。make就是根据Makefile文件中写的规则，执行对应的命令，然后得到目标产物。</p><p>日常生活中，和构建最类似的一个场景就是做菜。输入各种食材，然后按固定的工序，最后得到一盘菜。当然，做同样一道菜，由于需求不同，做出来的东西也不尽相同。比如，宫保鸡丁这道菜，回民要求不能放大油、口淡的要求少放盐和各种油、辣不怕的男女汉子们可以要求多放辣子....总之，做菜包含固定的工序，但是对于不同条件或需求，需要做不同的处理。</p><p>在Gradle爆红之前，常用的构建工具是ANT，然后又进化到Maven。ANT和Maven这两个工具其实也还算方便，现在还有很多地方在使用。但是二者都有一些缺点，所以让更懒得人觉得不是那么方便。比如，Maven编译规则是用XML来编写的。XML虽然通俗易懂，但是很难在xml中描述<em>if{某条件成立，编译某文件}/else{编译其他文件}</em>这样有不同条件的任务。</p><p>怎么解决？怎么解决好？对程序员而言，自然是编程解决，但是有几个小要求：</p><p></p><ul><li>这种“编程”不要搞得和程序员理解的编程那样复杂。寥寥几笔，轻轻松松把要做的事情描述出来就最好不过。所以，Gradle选择了<span style="color: red;">Groovy</span>。<span style="color: red;">Groovy</span>基于Java并拓展了Java。 Java程序员可以无缝切换到使用Groovy开发程序。Groovy说白了就是把写Java程序变得像写脚本一样简单。写完就可以执行，Groovy内部会将其编译成Javaclass然后启动虚拟机来执行。当然，这些底层的渣活不需要你管。</li><li>除了可以用很灵活的语言来写构建规则外，Gradle另外一个特点就是它是一种DSL，即<em>Domain Specific Language</em>，领域相关语言。什么是<span style="color: rgb(152, 72, 6);">DSL</span>，说白了它是某个行业中的行话。还是不明白？徐克导演得《智取威虎山》中就有很典型的<span style="color: rgb(152, 72, 6);">DSL</span>使用描述，比如：</li></ul><p></p><div style="background: rgb(242, 242, 242);"><p>------------------------------------------------------------------------------</p><p><span style="color:#6666cc;">土匪：蘑菇，你哪路？什么价？（什么人？到哪里去？）</span></p><p><span style="color:#6666cc;">杨子荣：哈！想啥来啥，想吃奶来了妈妈，想娘家的人，孩子他舅舅来了。（找同行）</span></p><p><span style="color:#6666cc;">杨子荣：拜见三爷！</span></p><p><span style="color:#6666cc;">土匪：天王盖地虎！（你好大的胆！敢来气你的祖宗？）</span></p><p><span style="color:#6666cc;">杨子荣：宝塔镇河妖！（要是那样，叫我从山上摔死，掉河里淹死。）</span></p><p><span style="color:#6666cc;">土匪：野鸡闷头钻，哪能上天王山！（你不是正牌的。）</span></p><p><span style="color:#6666cc;">杨子荣：地上有的是米，喂呀，有根底！（老子是正牌的，老牌的。）</span></p><p><span style="background-color: rgb(242, 242, 242);">------------------------------------------------------------------------------</span><br></p></div><p>Gradle中也有类似的行话，比如sourceSets代表源文件的集合等.....太多了，记不住。以后我们都会接触到这些行话。那么，对使用者而言，这些行话的好处是什么呢？这就是：</p><p>一句行话可以包含很多意思，而且在这个行当里的人一听就懂，不用解释。另外，基于行话，我们甚至可以建立一个模板，使用者只要往这个模板里填必须要填的内容，Gradle就可以非常漂亮得完成工作，得到想要的东西。</p><div style="background:#F2F2F2;"><p>这就和现在的智能炒菜机器似的，只要选择菜谱，把食材准备好，剩下的事情就不用你操心了。吃货们对这种做菜方式肯定是以反感为主，太没有特色了。但是程序员对Gradle类似做法却热烈拥抱。</p></div><p>到此，大家应该明白要真正学会Gradle恐怕是离不开下面两个基础知识：</p><p></p><ul><li>Groovy，由于它基于Java，所以我们仅介绍Java之外的东西。了解Groovy语言是掌握Gradle的基础。</li><li>Gradle作为一个工具，它的行话和它“为人处事”的原则。</li></ul><p></p><h2><a name="t3"></a>三、Groovy介绍</h2><p>Groovy是一种动态语言。这种语言比较有特点，它和Java一样，也运行于Java虚拟机中。恩？？对头，简单粗暴点儿看，你可以认为Groovy扩展了Java语言。比如，Groovy对自己的定义就是：<em>Groovy是在 java平台上的、 具有像Python， Ruby 和 Smalltalk 语言特性的灵活动态语言， Groovy保证了这些特性像 Java语法一样被 Java开发者使用。</em></p><p>除了语言和Java相通外，Groovy有时候又像一种脚本语言。前文也提到过，当我执行Groovy脚本时，Groovy会先将其编译成Java类字节码，然后通过Jvm来执行这个Java类。图1展示了Java、Groovy和Jvm之间的关系。</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>                                                                      </p>  <p><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905192824392" alt=""><br></p><p style="text-align: center;">图1&nbsp; Java、Groovy和JVM的关系</p></td> </tr></tbody></table></div><br clear="ALL"><p><em>实际上，由于Groovy Code在真正执行的时候已经变成了Java字节码，所以JVM根本不知道自己运行的是Groovy代码</em>。</p><p>下面我们将介绍Groovy。由于此文的主要目的是Gradle，所以我们不会过多讨论Groovy中细枝末节的东西，而是把知识点集中在以后和Gradle打交道时一些常用的地方上。</p><h3><a name="t4"></a>3.1&nbsp; Groovy开发环境</h3><p>在学习本节的时候，最好部署一下Groovy开发环境。根据Groovy官网的介绍（<em>http://www.groovy-lang.org/download.html#gvm</em>），部署Groovy开发环境非常简单，在Ubuntu或者cygwin之类的地方：</p><p></p><ul><li>curl -s get.gvmtool.net | bash</li><li>source"$HOME/.gvm/bin/gvm-init.sh"</li><li>gvm install groovy</li></ul><p></p><p>执行完最后一步，Groovy就下载并安装了。图1是安装时候的示意图</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905192939249" alt=""><br></p><p style="text-align: center;">图1&nbsp; Groovy安装示意图</p></td> </tr></tbody></table></div><br clear="ALL"><p>然后，创建一个test.groovy文件，里边只有一行代码：</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 3194px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_1" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>println&nbsp;</span><span class="string">"hello&nbsp;groovy"</span><span>&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">println "hello groovy"</pre><br><br><p></p><p>执行groovy test.groovy，输出结果如图2所示：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905192952248" alt=""><br></p><p style="text-align: center;">图2&nbsp; 执行groovy脚本</p></td> </tr></tbody></table></div><br clear="ALL"><p>亲们，必须要完成上面的操作啊。做完后，有什么感觉和体会？</p><p><em>最大的感觉可能就是groovy和shell脚本，或者python好类似。</em></p><p>另外，除了可以直接使用JDK之外，Groovy还有一套GDK，网址是<strong><span style="color:red;">http://www.groovy-lang.org/api.html</span></strong>。</p><div style="background:#F2F2F2;"><p>说实话，看了这么多家API文档，还是Google的Android API文档做得好。其页面中右上角有一个搜索栏，在里边输入一些关键字，瞬间就能列出候选类，相关文档，方便得不得了啊.....</p></div><h3><a name="t5"></a>3.2&nbsp; 一些前提知识</h3><p>为了后面讲述方面，这里先介绍一些前提知识。初期接触可能有些别扭，看习惯就好了。</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 3653px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_2" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>l&nbsp;Groovy注释标记和Java一样，支持</span><span class="comment">//或者/**/</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>l&nbsp;Groovy语句可以不用分号结尾。Groovy为了尽量减少代码的输入，确实煞费苦心&nbsp;&nbsp;</span></li><li class="alt"><span>l&nbsp;Groovy中支持动态类型，即定义变量的时候可以不指定其类型。Groovy中，变量定义可以使用关键字def。注意，虽然def不是必须的，但是为了代码清晰，建议还是使用def关键字&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;def&nbsp;variable1&nbsp;=&nbsp;<span class="number">1</span><span>&nbsp;&nbsp;&nbsp;</span><span class="comment">//可以不使用分号结尾</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;def&nbsp;varable2&nbsp;=&nbsp;<span class="string">"I&nbsp;ama&nbsp;person"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;def&nbsp;&nbsp;<span class="keyword">int</span><span>&nbsp;x&nbsp;=&nbsp;</span><span class="number">1</span><span>&nbsp;&nbsp;</span><span class="comment">//变量定义时，也可以直接指定类型</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>l&nbsp;&nbsp;&nbsp;函数定义时，参数的类型也可以不指定。比如&nbsp;&nbsp;</span></li><li class=""><span>String&nbsp;testFunction(arg1,arg2){<span class="comment">//无需指定参数类型</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;...&nbsp;&nbsp;</span></li><li class=""><span>}&nbsp;&nbsp;</span></li><li class="alt"><span>l&nbsp;除了变量定义可以不指定类型外，Groovy中函数的返回值也可以是无类型的。比如：&nbsp;&nbsp;</span></li><li class=""><span><span class="comment">//无类型的函数定义，必须使用def关键字</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>def&nbsp;&nbsp;nonReturnTypeFunc(){&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;last_line&nbsp;&nbsp;&nbsp;<span class="comment">//最后一行代码的执行结果就是本函数的返回值</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li><li class=""><span><span class="comment">//如果指定了函数返回类型，则可不必加def关键字来定义函数</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>String&nbsp;getString(){&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span class="string">"I&nbsp;am&nbsp;a&nbsp;string"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">l Groovy注释标记和Java一样，支持//或者/**/
l Groovy语句可以不用分号结尾。Groovy为了尽量减少代码的输入，确实煞费苦心
l Groovy中支持动态类型，即定义变量的时候可以不指定其类型。Groovy中，变量定义可以使用关键字def。注意，虽然def不是必须的，但是为了代码清晰，建议还是使用def关键字
   def variable1 = 1   //可以不使用分号结尾
   def varable2 = "I ama person"
  def  int x = 1  //变量定义时，也可以直接指定类型
l   函数定义时，参数的类型也可以不指定。比如
String testFunction(arg1,arg2){//无需指定参数类型
  ...
}
l 除了变量定义可以不指定类型外，Groovy中函数的返回值也可以是无类型的。比如：
//无类型的函数定义，必须使用def关键字
def  nonReturnTypeFunc(){
    last_line   //最后一行代码的执行结果就是本函数的返回值
}
//如果指定了函数返回类型，则可不必加def关键字来定义函数
String getString(){
   return"I am a string"
}</pre><br><br><p></p><p>其实，所谓的无返回类型的函数，我估计内部都是按返回Object类型来处理的。毕竟，Groovy是基于Java的，而且最终会转成Java Code运行在JVM上</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 4160px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_3" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=3&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>l&nbsp;函数返回值：Groovy的函数里，可以不使用returnxxx来设置xxx为函数返回值。如果不使用</span><span class="keyword">return</span><span>语句的话，则函数里最后一句代码的执行结果被设置成返回值。比如&nbsp;&nbsp;</span></span></li><li class=""><span><span class="comment">//下面这个函数的返回值是字符串"getSomething&nbsp;return&nbsp;value"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>def&nbsp;getSomething(){&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">"getSomething&nbsp;return&nbsp;value"</span><span>&nbsp;</span><span class="comment">//如果这是最后一行代码，则返回类型为String</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="number">1000</span><span class="comment">//如果这是最后一行代码，则返回类型为Integer</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">l 函数返回值：Groovy的函数里，可以不使用returnxxx来设置xxx为函数返回值。如果不使用return语句的话，则函数里最后一句代码的执行结果被设置成返回值。比如
//下面这个函数的返回值是字符串"getSomething return value"
def getSomething(){
     "getSomething return value" //如果这是最后一行代码，则返回类型为String
      1000//如果这是最后一行代码，则返回类型为Integer
}</pre><br><br><p></p><p>注意，如果函数定义时候指明了返回值类型的话，函数中则必须返回正确的数据类型，否则运行时报错。如果使用了动态类型的话，你就可以返回任何类型了。</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 4459px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_4" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=4&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>l&nbsp;Groovy对字符串支持相当强大，充分吸收了一些脚本语言的优点：&nbsp;&nbsp;</span></span></li><li class=""><span><span class="number">1</span><span>&nbsp;&nbsp;单引号</span><span class="string">''</span><span>中的内容严格对应Java中的String，不对$符号进行转义&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;defsingleQuote=<span class="string">'I&nbsp;am&nbsp;$&nbsp;dolloar'</span><span>&nbsp;&nbsp;</span><span class="comment">//输出就是I&nbsp;am&nbsp;$&nbsp;dolloar</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="number">2</span><span>&nbsp;&nbsp;双引号</span><span class="string">""</span><span>的内容则和脚本语言的处理有点像，如果字符中有$号的话，则它会$表达式先求值。&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;defdoubleQuoteWithoutDollar&nbsp;=&nbsp;<span class="string">"I&nbsp;am&nbsp;one&nbsp;dollar"</span><span>&nbsp;</span><span class="comment">//输出&nbsp;I&nbsp;am&nbsp;one&nbsp;dollar</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;def&nbsp;x&nbsp;=&nbsp;<span class="number">1</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;defdoubleQuoteWithDollar&nbsp;=&nbsp;<span class="string">"I&nbsp;am&nbsp;$x&nbsp;dolloar"</span><span>&nbsp;</span><span class="comment">//输出I&nbsp;am&nbsp;1&nbsp;dolloar</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="number">3</span><span>&nbsp;三个引号</span><span class="string">''</span><span class="string">'xxx'</span><span class="string">''</span><span>中的字符串支持随意换行&nbsp;比如&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;defmultieLines&nbsp;=&nbsp;<span class="string">''</span><span>'&nbsp;begin&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line&nbsp;&nbsp;<span class="number">1</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line&nbsp;&nbsp;<span class="number">2</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;<span class="string">''</span><span>'&nbsp;&nbsp;</span></span></li><li class="alt"><span>l&nbsp;最后，除了每行代码不用加分号外，Groovy中函数调用的时候还可以不加括号。比如：&nbsp;&nbsp;</span></li><li class=""><span>println(<span class="string">"test"</span><span>)&nbsp;---&gt;&nbsp;println</span><span class="string">"test"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>注意，虽然写代码的时候，对于函数调用可以不带括号，但是Groovy经常把属性和函数调用混淆。比如&nbsp;&nbsp;</span></li><li class=""><span>def&nbsp;getSomething(){&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;<span class="string">"hello"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">l Groovy对字符串支持相当强大，充分吸收了一些脚本语言的优点：
1  单引号''中的内容严格对应Java中的String，不对$符号进行转义
   defsingleQuote='I am $ dolloar'  //输出就是I am $ dolloar
2  双引号""的内容则和脚本语言的处理有点像，如果字符中有$号的话，则它会$表达式先求值。
   defdoubleQuoteWithoutDollar = "I am one dollar" //输出 I am one dollar
   def x = 1
   defdoubleQuoteWithDollar = "I am $x dolloar" //输出I am 1 dolloar
3 三个引号'''xxx'''中的字符串支持随意换行 比如
   defmultieLines = ''' begin
     line  1
     line  2
     end '''
l 最后，除了每行代码不用加分号外，Groovy中函数调用的时候还可以不加括号。比如：
println("test") ---&gt; println"test"
注意，虽然写代码的时候，对于函数调用可以不带括号，但是Groovy经常把属性和函数调用混淆。比如
def getSomething(){
  "hello"
}</pre><br><br><p></p><p>getSomething<span style="color:red;">()</span>&nbsp;&nbsp;//如果不加括号的话，Groovy会误认为getSomething是一个变量。比如：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center" style="text-align: center;"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905193011828" alt=""><br></p><p style="text-align: center;">图3&nbsp; 错误示意</p></td> </tr></tbody></table></div><br clear="ALL"><p>所以，调用函数要不要带括号，我个人意见是如果这个函数是Groovy API或者Gradle API中比较常用的，比如println，就可以不带括号。否则还是带括号。Groovy自己也没有太好的办法解决这个问题，只能兵来将挡水来土掩了。</p><p>好了，了解上面一些基础知识后，我们再介绍点深入的内容。</p><h3><a name="t6"></a>3.3&nbsp; Groovy中的数据类型</h3><p>Groovy中的数据类型我们就介绍两种和Java不太一样的：</p><p></p><ul><li>一个是Java中的基本数据类型。</li><li>另外一个是Groovy中的容器类。</li><li>最后一个非常重要的是闭包。</li></ul><p></p><p>放心，这里介绍的东西都很简单</p><h4><a name="t7"></a>3.3.1&nbsp; 基本数据类型</h4><p>作为动态语言，Groovy世界中的所有事物都是对象。所以，int，boolean这些Java中的基本数据类型，在Groovy代码中其实对应的是它们的包装数据类型。比如int对应为Integer，boolean对应为Boolean。比如下图中的代码执行结果：</p><p> </p><p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905193120964" alt=""><br></p><p style="text-align: center;">图4&nbsp; int实际上是Integer</p><h4><a name="t8"></a>3.3.2&nbsp; 容器类</h4><p>Groovy中的容器类很简单，就三种：</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>List：链表，其底层对应Java中的List接口，一般用ArrayList作为真正的实现类。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>Map：键-值表，其底层对应Java中的LinkedHashMap。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>Range：范围，它其实是List的一种拓展。</li></ul><p></p><p>对容器而言，我们最重要的是了解它们的用法。下面是一些简单的例子：</p><h5><a name="t9"></a>1.&nbsp; List类</h5><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 5783px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_5" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_5" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=5&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>变量定义：List变量由[]定义，比如&nbsp;&nbsp;</span></span></li><li class=""><span>def&nbsp;aList&nbsp;=&nbsp;[<span class="number">5</span><span>,</span><span class="string">'string'</span><span>,</span><span class="keyword">true</span><span>]&nbsp;</span><span class="comment">//List由[]定义，其元素可以是任何对象</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>变量存取：可以直接通过索引存取，而且不用担心索引越界。如果索引超过当前链表长度，List会自动&nbsp;&nbsp;</span></li><li class=""><span>往该索引添加元素&nbsp;&nbsp;</span></li><li class="alt"><span><span class="keyword">assert</span><span>&nbsp;aList[</span><span class="number">1</span><span>]&nbsp;==&nbsp;</span><span class="string">'string'</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="keyword">assert</span><span>&nbsp;aList[</span><span class="number">5</span><span>]&nbsp;==&nbsp;</span><span class="keyword">null</span><span>&nbsp;</span><span class="comment">//第6个元素为空</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>aList[<span class="number">100</span><span>]&nbsp;=&nbsp;</span><span class="number">100</span><span>&nbsp;</span><span class="comment">//设置第101个元素的值为10</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="keyword">assert</span><span>&nbsp;aList[</span><span class="number">100</span><span>]&nbsp;==&nbsp;</span><span class="number">100</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>那么，aList到现在为止有多少个元素呢？&nbsp;&nbsp;</span></li><li class=""><span>println&nbsp;aList.size&nbsp;&nbsp;===&gt;结果是<span class="number">101</span><span>&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">变量定义：List变量由[]定义，比如
def aList = [5,'string',true] //List由[]定义，其元素可以是任何对象
变量存取：可以直接通过索引存取，而且不用担心索引越界。如果索引超过当前链表长度，List会自动
往该索引添加元素
assert aList[1] == 'string'
assert aList[5] == null //第6个元素为空
aList[100] = 100 //设置第101个元素的值为10
assert aList[100] == 100
那么，aList到现在为止有多少个元素呢？
println aList.size  ===&gt;结果是101</pre><br><br><p></p><h5><a name="t10"></a>2.&nbsp; Map类</h5><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 6132px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_6" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_6" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=6&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>容器变量定义&nbsp;&nbsp;</span></span></li><li class=""><span>变量定义：Map变量由[:]定义，比如&nbsp;&nbsp;</span></li><li class="alt"><span>def&nbsp;aMap&nbsp;=&nbsp;[<span class="string">'key1'</span><span>:</span><span class="string">'value1'</span><span>,</span><span class="string">'key2'</span><span>:</span><span class="keyword">true</span><span>]&nbsp;&nbsp;</span></span></li><li class=""><span>Map由[:]定义，注意其中的冒号。冒号左边是key，右边是Value。key必须是字符串，value可以是任何对象。另外，key可以用<span class="string">''</span><span>或</span><span class="string">""</span><span>包起来，也可以不用引号包起来。比如&nbsp;&nbsp;</span></span></li><li class="alt"><span>def&nbsp;aNewMap&nbsp;=&nbsp;[key1:<span class="string">"value"</span><span>,key2:</span><span class="keyword">true</span><span>]</span><span class="comment">//其中的key1和key2默认被</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>处理成字符串<span class="string">"key1"</span><span>和</span><span class="string">"key2"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>不过Key要是不使用引号包起来的话，也会带来一定混淆，比如&nbsp;&nbsp;</span></li><li class=""><span>def&nbsp;key1=<span class="string">"wowo"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>def&nbsp;aConfusedMap=[key1:<span class="string">"who&nbsp;am&nbsp;i?"</span><span>]&nbsp;&nbsp;</span></span></li><li class=""><span>aConfuseMap中的key1到底是<span class="string">"key1"</span><span>还是变量key1的值“wowo”？显然，答案是字符串</span><span class="string">"key1"</span><span>。如果要是</span><span class="string">"wowo"</span><span>的话，则aConfusedMap的定义必须设置成：&nbsp;&nbsp;</span></span></li><li class="alt"><span>def&nbsp;aConfusedMap=[(key1):<span class="string">"who&nbsp;am&nbsp;i?"</span><span>]&nbsp;&nbsp;</span></span></li><li class=""><span>Map中元素的存取更加方便，它支持多种方法：&nbsp;&nbsp;</span></li><li class="alt"><span>println&nbsp;aMap.keyName&nbsp;&nbsp;&nbsp;&nbsp;&lt;==这种表达方法好像key就是aMap的一个成员变量一样&nbsp;&nbsp;</span></li><li class=""><span>println&nbsp;aMap[<span class="string">'keyName'</span><span>]&nbsp;&lt;==这种表达方法更传统一点&nbsp;&nbsp;</span></span></li><li class="alt"><span>aMap.anotherkey&nbsp;=&nbsp;<span class="string">"i&nbsp;am&nbsp;map"</span><span>&nbsp;&nbsp;&lt;==为map添加新元素&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">容器变量定义
变量定义：Map变量由[:]定义，比如
def aMap = ['key1':'value1','key2':true]
Map由[:]定义，注意其中的冒号。冒号左边是key，右边是Value。key必须是字符串，value可以是任何对象。另外，key可以用''或""包起来，也可以不用引号包起来。比如
def aNewMap = [key1:"value",key2:true]//其中的key1和key2默认被
处理成字符串"key1"和"key2"
不过Key要是不使用引号包起来的话，也会带来一定混淆，比如
def key1="wowo"
def aConfusedMap=[key1:"who am i?"]
aConfuseMap中的key1到底是"key1"还是变量key1的值“wowo”？显然，答案是字符串"key1"。如果要是"wowo"的话，则aConfusedMap的定义必须设置成：
def aConfusedMap=[(key1):"who am i?"]
Map中元素的存取更加方便，它支持多种方法：
println aMap.keyName    &lt;==这种表达方法好像key就是aMap的一个成员变量一样
println aMap['keyName'] &lt;==这种表达方法更传统一点
aMap.anotherkey = "i am map"  &lt;==为map添加新元素</pre><br><br><p></p><h5><a name="t11"></a>3.&nbsp; Range类</h5><p>Range是Groovy对List的一种拓展，变量定义和大体的使用方法如下：</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 6633px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_7" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_7" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=7&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>def&nbsp;aRange&nbsp;=&nbsp;</span><span class="number">1</span><span>..</span><span class="number">5</span><span>&nbsp;&lt;==Range类型的变量&nbsp;由begin值+两个点+end值表示&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;左边这个aRange包含<span class="number">1</span><span>,</span><span class="number">2</span><span>,</span><span class="number">3</span><span>,</span><span class="number">4</span><span>,</span><span class="number">5</span><span>这</span><span class="number">5</span><span>个值&nbsp;&nbsp;</span></span></li><li class="alt"><span>如果不想包含最后一个元素，则&nbsp;&nbsp;</span></li><li class=""><span>def&nbsp;aRangeWithoutEnd&nbsp;=&nbsp;<span class="number">1</span><span>..&lt;</span><span class="number">5</span><span>&nbsp;&nbsp;&lt;==包含</span><span class="number">1</span><span>,</span><span class="number">2</span><span>,</span><span class="number">3</span><span>,</span><span class="number">4</span><span>这</span><span class="number">4</span><span>个元素&nbsp;&nbsp;</span></span></li><li class="alt"><span>println&nbsp;aRange.from&nbsp;&nbsp;</span></li><li class=""><span>println&nbsp;aRange.to&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">def aRange = 1..5 &lt;==Range类型的变量 由begin值+两个点+end值表示
                      左边这个aRange包含1,2,3,4,5这5个值
如果不想包含最后一个元素，则
def aRangeWithoutEnd = 1..&lt;5  &lt;==包含1,2,3,4这4个元素
println aRange.from
println aRange.to</pre><br><br><p></p><h3><a name="t12"></a>3.3.4&nbsp; Groovy API的一些秘笈</h3><p>前面讲这些东西，主要是让大家了解Groovy的语法。实际上在coding的时候，是离不开SDK的。由于Groovy是动态语言，所以要使用它的SDK也需要掌握一些小诀窍。</p><p><span style="background:yellow;">Groovy</span><span style="background:yellow;">的</span><span style="background:yellow;">API</span><span style="background:yellow;">文档位于</span><span style="background:yellow;">http://www.groovy-lang.org/api.html</span></p><p>以上文介绍的Range为例，我们该如何更好得使用它呢？</p><p><span style="color:#00B050;">l&nbsp;</span>先定位到Range类。它位于groovy.lang包中：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905193143290" alt=""><br></p><p style="text-align: center;">图5&nbsp; Range类API文档</p></td> </tr></tbody></table></div><br clear="ALL"><p>有了API文档，你就可以放心调用其中的函数了。不过，不过，不过：我们刚才代码中用到了Range.from/to属性值，但翻看Range API文档的时候，其实并没有这两个成员变量。图6是Range的方法</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905193206100" alt=""><br></p><p style="text-align: center;">图6&nbsp; Range类的方法</p></td> </tr></tbody></table></div><br clear="ALL"><p>文档中并没有说明Range有from和to这两个属性，但是却有getFrom和getTo这两个函数。<em>What happened？</em>原来：</p><p>根据Groovy的原则，如果一个类中有名为xxyyzz这样的属性（其实就是成员变量），Groovy会自动为它添加getXxyyzz和setXxyyzz两个函数，用于获取和设置xxyyzz属性值。</p><div style="background:#F2F2F2;"><p>注意，get和set后第一个字母是大写的</p></div><p>所以，当你看到Range中有getFrom和getTo这两个函数时候，就得知道潜规则下，Range有from和to这两个属性。当然，由于它们不可以被外界设置，所以没有公开setFrom和setTo函数。</p><h3><a name="t13"></a>3.4&nbsp; 闭包</h3><h4><a name="t14"></a>3.4.1&nbsp; 闭包的样子</h4><p>闭包，英文叫Closure，是Groovy中非常重要的一个数据类型或者说一种概念了。闭包的历史来源，种种好处我就不说了。我们直接看怎么使用它！</p><p>闭包，是一种数据类型，它代表了一段可执行的代码。其外形如下：</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 8470px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_8" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_8" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=8&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>def&nbsp;aClosure&nbsp;=&nbsp;{</span><span class="comment">//闭包是一段代码，所以需要用花括号括起来..</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;Stringparam1,&nbsp;<span class="keyword">int</span><span>&nbsp;param2&nbsp;-&gt;&nbsp;&nbsp;</span><span class="comment">//这个箭头很关键。箭头前面是参数定义，箭头后面是代码</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;println<span class="string">"this&nbsp;is&nbsp;code"</span><span>&nbsp;</span><span class="comment">//这是代码，最后一句是返回值，</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;<span class="comment">//也可以使用return，和Groovy中普通函数一样</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">def aClosure = {//闭包是一段代码，所以需要用花括号括起来..
    Stringparam1, int param2 -&gt;  //这个箭头很关键。箭头前面是参数定义，箭头后面是代码
    println"this is code" //这是代码，最后一句是返回值，
   //也可以使用return，和Groovy中普通函数一样
}</pre><br><br><p></p><p>简而言之，Closure的定义格式是：</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 8707px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_9" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_9" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=9&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>&lt;pre&nbsp;name=</span><span class="string">"code"</span><span>&nbsp;</span><span class="keyword">class</span><span>=</span><span class="string">"java"</span><span>&gt;def&nbsp;xxx&nbsp;=&nbsp;{paramters&nbsp;-&gt;&nbsp;code}&nbsp;&nbsp;</span><span class="comment">//或者</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>def&nbsp;xxx&nbsp;=&nbsp;{无参数，纯code}&nbsp;&nbsp;这种<span class="keyword">case</span><span>不需要-&gt;符号&lt;/pre&gt;&lt;br&gt;&lt;br&gt;&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;"><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 0px; top: 0px; width: 0px; height: 0px; z-index: 99;"><embed id="ZeroClipboardMovie_10" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="0" height="0" name="ZeroClipboardMovie_10" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=10&amp;width=0&amp;height=0" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>def&nbsp;xxx&nbsp;=&nbsp;{paramters&nbsp;-&gt;&nbsp;code}&nbsp;&nbsp;</span><span class="comment">//或者</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>def&nbsp;xxx&nbsp;=&nbsp;{无参数，纯code}&nbsp;&nbsp;这种<span class="keyword">case</span><span>不需要-&gt;符号&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">def xxx = {paramters -&gt; code}  //或者
def xxx = {无参数，纯code}  这种case不需要-&gt;符号</pre><br><br></pre><br><br><p></p><p>说实话，从C/C++语言的角度看，闭包和函数指针很像。闭包定义好后，要调用它的方法就是：</p><p>闭包对象.<span style="color:red;">call(</span><span style="color:red;">参数</span><span style="color:red;">)</span>&nbsp; 或者更像函数指针调用的方法：</p><p>闭包对象<span style="color:red;">(</span><span style="color:red;">参数</span><span style="color:red;">)</span>&nbsp; </p><p>比如：</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 8968px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_11" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_11" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=11&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>aClosure.call(</span><span class="string">"this&nbsp;is&nbsp;string"</span><span>,</span><span class="number">100</span><span>)&nbsp;&nbsp;或者&nbsp;&nbsp;</span></span></li><li class=""><span>aClosure(<span class="string">"this&nbsp;is&nbsp;string"</span><span>,&nbsp;</span><span class="number">100</span><span>)&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">aClosure.call("this is string",100)  或者
aClosure("this is string", 100)</pre><br><br><p></p><p>上面就是一个闭包的定义和使用。在闭包中，还需要注意一点：</p><p><em>如果闭包没定义参数的话，则隐含有一个参数，这个参数名字叫it，和this的作用类似。it代表闭包的参数。</em></p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 9177px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_12" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_12" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=12&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>比如：&nbsp;&nbsp;</span></span></li><li class=""><span>def&nbsp;greeting&nbsp;=&nbsp;{&nbsp;<span class="string">"Hello,&nbsp;$it!"</span><span>&nbsp;}&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="keyword">assert</span><span>&nbsp;greeting(</span><span class="string">'Patrick'</span><span>)&nbsp;==&nbsp;</span><span class="string">'Hello,&nbsp;Patrick!'</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>等同于：&nbsp;&nbsp;</span></li><li class="alt"><span>def&nbsp;greeting&nbsp;=&nbsp;{&nbsp;it&nbsp;-&gt;&nbsp;<span class="string">"Hello,&nbsp;$it!"</span><span>}&nbsp;&nbsp;</span></span></li><li class=""><span><span class="keyword">assert</span><span>&nbsp;greeting(</span><span class="string">'Patrick'</span><span>)&nbsp;==&nbsp;</span><span class="string">'Hello,&nbsp;Patrick!'</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>但是，如果在闭包定义时，采用下面这种写法，则表示闭包没有参数！&nbsp;&nbsp;</span></li><li class=""><span>def&nbsp;noParamClosure&nbsp;=&nbsp;{&nbsp;-&gt;&nbsp;<span class="keyword">true</span><span>&nbsp;}&nbsp;&nbsp;</span></span></li><li class="alt"><span>这个时候，我们就不能给noParamClosure传参数了！&nbsp;&nbsp;</span></li><li class=""><span>noParamClosure&nbsp;(<span class="string">"test"</span><span>)&nbsp;&nbsp;&lt;==报错喔！&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">比如：
def greeting = { "Hello, $it!" }
assert greeting('Patrick') == 'Hello, Patrick!'
等同于：
def greeting = { it -&gt; "Hello, $it!"}
assert greeting('Patrick') == 'Hello, Patrick!'
但是，如果在闭包定义时，采用下面这种写法，则表示闭包没有参数！
def noParamClosure = { -&gt; true }
这个时候，我们就不能给noParamClosure传参数了！
noParamClosure ("test")  &lt;==报错喔！</pre><br><br><p></p><h4><a name="t15"></a>3.4.2&nbsp; Closure使用中的注意点</h4><h5><a name="t16"></a>1.&nbsp; 省略圆括号</h5><p>闭包在Groovy中大量使用，比如很多类都定义了一些函数，这些函数最后一个参数都是一个闭包。比如：</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 9596px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_13" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_13" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=13&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;&lt;T&gt;&nbsp;List&lt;T&gt;each(List&lt;T&gt;&nbsp;self,&nbsp;Closure&nbsp;closure)&nbsp;&nbsp;</span></span></li><li class=""><span>上面这个函数表示针对List的每一个元素都会调用closure做一些处理。这里的closure，就有点回调函数的感觉。但是，在使用这个each函数的时候，我们传递一个怎样的Closure进去呢？比如：&nbsp;&nbsp;</span></li><li class="alt"><span>def&nbsp;iamList&nbsp;=&nbsp;[<span class="number">1</span><span>,</span><span class="number">2</span><span>,</span><span class="number">3</span><span>,</span><span class="number">4</span><span>,</span><span class="number">5</span><span>]&nbsp;&nbsp;</span><span class="comment">//定义一个List</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>iamList.each{&nbsp;<span class="comment">//调用它的each，这段代码的格式看不懂了吧？each是个函数，圆括号去哪了？</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;println&nbsp;it&nbsp;&nbsp;</span></li><li class=""><span>}&nbsp;&nbsp;</span></li><li class="alt"><span>上面代码有两个知识点：&nbsp;&nbsp;</span></li><li class=""><span>l&nbsp;each函数调用的圆括号不见了！原来，Groovy中，当函数的最后一个参数是闭包的话，可以省略圆括号。比如&nbsp;&nbsp;</span></li><li class="alt"><span>def&nbsp;testClosure(<span class="keyword">int</span><span>&nbsp;a1,String&nbsp;b1,&nbsp;Closure&nbsp;closure){&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//dosomething</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;closure()&nbsp;<span class="comment">//调用闭包</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>}&nbsp;&nbsp;</span></li><li class="alt"><span>那么调用的时候，就可以免括号！&nbsp;&nbsp;</span></li><li class=""><span>testClosure&nbsp;(<span class="number">4</span><span>,&nbsp;</span><span class="string">"test"</span><span>,&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;println<span class="string">"i&nbsp;am&nbsp;in&nbsp;closure"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>}&nbsp;)&nbsp;&nbsp;<span class="comment">//红色的括号可以不写..</span><span>&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">public static &lt;T&gt; List&lt;T&gt;each(List&lt;T&gt; self, Closure closure)
上面这个函数表示针对List的每一个元素都会调用closure做一些处理。这里的closure，就有点回调函数的感觉。但是，在使用这个each函数的时候，我们传递一个怎样的Closure进去呢？比如：
def iamList = [1,2,3,4,5]  //定义一个List
iamList.each{ //调用它的each，这段代码的格式看不懂了吧？each是个函数，圆括号去哪了？
      println it
}
上面代码有两个知识点：
l each函数调用的圆括号不见了！原来，Groovy中，当函数的最后一个参数是闭包的话，可以省略圆括号。比如
def testClosure(int a1,String b1, Closure closure){
      //dosomething
     closure() //调用闭包
}
那么调用的时候，就可以免括号！
testClosure (4, "test", {
   println"i am in closure"
} )  //红色的括号可以不写..</pre><br><br><p></p><p>注意，这个特点非常关键，因为以后在Gradle中经常会出现图7这样的代码：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905193225923" alt=""><br></p><p style="text-align: center;">图7&nbsp; 闭包调用</p></td> </tr></tbody></table></div><br clear="ALL"><p>经常碰见图7这样的没有圆括号的代码。省略圆括号虽然使得代码简洁，看起来更像脚本语言，但是它这经常会让我confuse（不知道其他人是否有同感），以doLast为例，完整的代码应该按下面这种写法：</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 10271px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_14" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_14" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=14&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>&nbsp;doLast({&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;println<span class="string">'Hello&nbsp;world!'</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>})&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;"> doLast({
   println'Hello world!'
})</pre><br><br><p></p><p>有了圆括号，你会知道 doLast只是把一个Closure对象传了进去。很明显，它不代表这段脚本解析到doLast的时候就会调用<span style="color:red;">println 'Hello world!'</span> 。</p><p>但是把圆括号去掉后，就感觉好像<span style="color:red;">println 'Hello world!'</span>立即就会被调用一样！</p><h5><a name="t17"></a>2.&nbsp; 如何确定Closure的参数</h5><p>另外一个比较让人头疼的地方是，Closure的参数该怎么搞？还是刚才的each函数：</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 10590px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_15" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_15" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=15&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;&lt;T&gt;&nbsp;List&lt;T&gt;&nbsp;each(List&lt;T&gt;self,&nbsp;Closure&nbsp;closure)&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">public static &lt;T&gt; List&lt;T&gt; each(List&lt;T&gt;self, Closure closure)</pre><br><br><p></p><p>如何使用它呢？比如：</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 10755px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_16" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_16" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=16&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>def&nbsp;iamList&nbsp;=&nbsp;[</span><span class="number">1</span><span>,</span><span class="number">2</span><span>,</span><span class="number">3</span><span>,</span><span class="number">4</span><span>,</span><span class="number">5</span><span>]&nbsp;&nbsp;</span><span class="comment">//定义一个List变量</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>iamList.each{&nbsp;<span class="comment">//调用它的each函数，只要传入一个Closure就可以了。</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;println&nbsp;it&nbsp;&nbsp;</span></li><li class=""><span>}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">def iamList = [1,2,3,4,5]  //定义一个List变量
iamList.each{ //调用它的each函数，只要传入一个Closure就可以了。
  println it
}</pre><br><br><p></p><p>看起来很轻松，其实：</p><p><span style="color:rgb(0, 176, 80);">l&nbsp;</span>对于each所需要的Closure，它的参数是什么？有多少个参数？返回值是什么？</p><p>我们能写成下面这样吗？</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 11026px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_17" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_17" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=17&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>iamList.each{String&nbsp;name,</span><span class="keyword">int</span><span>&nbsp;x&nbsp;-&gt;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;x&nbsp;&nbsp;</span></span></li><li class="alt"><span>}&nbsp;&nbsp;<span class="comment">//运行的时候肯定报错！</span><span>&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">iamList.each{String name,int x -&gt;
  return x
}  //运行的时候肯定报错！
</pre><br>所以，Closure虽然很方便，但是它一定会和使用它的上下文有极强的关联。要不，作为类似回调这样的东西，我如何知道调用者传递什么参数给Closure呢？<p></p><p>此问题如何破解？只能通过查询API文档才能了解上下文语义。比如下图8：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>          </p>  <p><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905193242319" width="198" height="133" alt=""><br></p><p style="text-align: center;"><br></p><p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905193459310" width="200" height="126" alt=""><br></p><p style="text-align: center;">图8&nbsp; 文档说明</p></td> </tr></tbody></table><br></div><br clear="ALL"><p>图8中：</p><p></p><ul><li>each函数说明中，将给指定的closure传递Set中的每一个item。所以，closure的参数只有一个。</li><li>findAll中，<strong><span style="color:red;">绝对抓瞎</span></strong>了。一个是没说明往Closure里传什么。另外没说明Closure的返回值是什么.....。</li></ul><p></p><p>对Map的findAll而言，Closure可以有两个参数。findAll会将Key和Value分别传进去。并且，Closure返回true，表示该元素是自己想要的。返回false表示该元素不是自己要找的。示意代码如图9所示：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center" style="text-align: left;"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905193642662" alt=""><br></p><p style="text-align: center;">图9&nbsp; Closure调用示例</p></td> </tr></tbody></table></div><br clear="ALL"><div style="background:#F2F2F2;"><p>Closure的使用有点坑，很大程度上依赖于你对API的熟悉程度，所以最初阶段，SDK查询是少不了的。</p></div><h3><a name="t18"></a>3.5&nbsp; 脚本类、文件I/O和XML操作</h3><p>最后，我们来看一下Groovy中比较高级的用法。</p><h4><a name="t19"></a>3.5.1&nbsp; 脚本类</h4><h5><a name="t20"></a>1.&nbsp; 脚本中import其他类</h5><p>Groovy中可以像Java那样写package，然后写类。比如在文件夹com/cmbc/groovy/目录中放一个文件，叫Test.groovy，如图10所示：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905193711206" alt=""><br></p><p style="text-align: center;">图10&nbsp; com/cmbc/groovy/Test.groovy文件</p></td> </tr></tbody></table></div><br clear="ALL"><p>你看，图10中的Test.groovy和Java类就很相似了。当然，如果不声明public/private等访问权限的话，Groovy中类及其变量默认都是public的。</p><p>现在，我们在测试的根目录下建立一个test.groovy文件。其代码如下所示：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905193733171" alt=""><br></p><p style="text-align: center;">图11&nbsp; test.groovy访问com/cmbc/groovy包</p></td> </tr></tbody></table></div><br clear="ALL"><p>你看，test.groovy先import了com.cmbc.groovy.Test类，然后创建了一个Test类型的对象，接着调用它的print函数。</p><p>这两个groovy文件的目录结构如图12所示：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905193800825" alt=""><br></p><p style="text-align: center;">图12&nbsp; Test.groovy和test.groovy目录结构</p></td> </tr></tbody></table></div><br clear="ALL"><p>在groovy中，系统自带会加载当前目录/子目录下的xxx.groovy文件。所以，当执行groovy test.groovy的时候，test.groovy import的Test类能被自动搜索并加载到。</p><h5><a name="t21"></a>2.&nbsp; 脚本到底是什么</h5><p>Java中，我们最熟悉的是类。但是我们在Java的一个源码文件中，不能不写class（interface或者其他....），而Groovy可以像写脚本一样，把要做的事情都写在xxx.groovy中，而且可以通过groovy xxx.groovy直接执行这个脚本。这到底是怎么搞的？</p><p>既然是基于Java的，Groovy会先把xxx.groovy中的内容转换成一个Java类。比如：</p><p>test.groovy的代码是：</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 13329px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_18" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_18" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=18&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>println&nbsp;</span><span class="string">'Groovy&nbsp;world!'</span><span>&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">println 'Groovy world!'</pre><br><br><p></p><p>Groovy把它转换成这样的Java类：</p><div style="background:#F2F2F2;"><p>执行<strong><span style="color:red;"> groovyc</span></strong>-d classes test.groovy</p><p><strong><span style="color:red;">groovyc</span></strong>是groovy的编译命令，-dclasses用于将编译得到的class文件拷贝到classes文件夹下</p></div><p>图13是test.groovy脚本转换得到的java class。用jd-gui反编译它的代码：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905193818456" alt=""><br></p><p style="text-align: center;">图13 groovy脚本反编译得到的Java类源码</p></td> </tr></tbody></table></div><br clear="ALL"><p>图13中：</p><p></p><ul><li>test.groovy被转换成了一个test类，它从script派生。</li><li><span style="color: red;">每一个脚本都会生成一个</span><span style="color: red;">static main</span><span style="color: red;">函数</span>。这样，当我们groovytest.groovy的时候，其实就是用java去执行这个main函数</li><li><em>脚本中的所有代码都会放到run函数中</em>。比如，println 'Groovy world'，这句代码实际上是包含在run函数里的。</li><li>如果脚本中定义了函数，则函数会被定义在test类中。</li></ul><p></p><div style="background:#F2F2F2;"><p><strong><span style="color:red;">groovyc</span></strong>是一个比较好的命令，读者要掌握它的用法。然后利用jd-gui来查看对应class的Java源码。</p></div><h5><a name="t22"></a>3.&nbsp; 脚本中的变量和作用域</h5><p>前面说了，xxx.groovy只要不是和Java那样的class，那么它就是一个脚本。而且脚本的代码其实都会被放到run函数中去执行。那么，在Groovy的脚本中，很重要的一点就是脚本中定义的<em>变量和它的作用域</em>。举例：</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 14458px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_19" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_19" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=19&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>def&nbsp;x&nbsp;=&nbsp;</span><span class="number">1</span><span>&nbsp;&lt;==注意，这个x有def（或者指明类型，比如&nbsp;</span><span class="keyword">int</span><span>&nbsp;x&nbsp;=&nbsp;</span><span class="number">1</span><span>）&nbsp;&nbsp;</span></span></li><li class=""><span>def&nbsp;printx(){&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;println&nbsp;x&nbsp;&nbsp;</span></li><li class=""><span>}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">def x = 1 &lt;==注意，这个x有def（或者指明类型，比如 int x = 1）
def printx(){
   println x
}</pre><br><br><p></p><p>printx()&nbsp;&lt;==报错，说x找不到</p><p>为什么？继续来看反编译后的class文件。</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905193919401" alt=""><br></p><p style="text-align: center;">图14&nbsp; 反编译后的test.class文件</p></td> </tr></tbody></table></div><br clear="ALL"><p>图14中：</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 15162px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_20" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_20" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=20&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>l&nbsp;printx被定义成test类的成员函数&nbsp;&nbsp;</span></span></li><li class=""><span>l&nbsp;def&nbsp;x&nbsp;=&nbsp;<span class="number">1</span><span>，这句话是在run中创建的。所以，x=</span><span class="number">1</span><span>从代码上看好像是在整个脚本中定义的，但实际上printx访问不了它。printx是test成员函数，除非x也被定义成test的成员函数，否则printx不能访问它。&nbsp;&nbsp;</span></span></li><li class="alt"><span>那么，如何使得printx能访问x呢？很简单，定义的时候不要加类型和def。即：&nbsp;&nbsp;</span></li><li class=""><span>x&nbsp;=&nbsp;<span class="number">1</span><span>&nbsp;&lt;==注意，去掉def或者类型&nbsp;&nbsp;</span></span></li><li class="alt"><span>def&nbsp;printx(){&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;println&nbsp;x&nbsp;&nbsp;</span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">l printx被定义成test类的成员函数
l def x = 1，这句话是在run中创建的。所以，x=1从代码上看好像是在整个脚本中定义的，但实际上printx访问不了它。printx是test成员函数，除非x也被定义成test的成员函数，否则printx不能访问它。
那么，如何使得printx能访问x呢？很简单，定义的时候不要加类型和def。即：
x = 1 &lt;==注意，去掉def或者类型
def printx(){
   println x
}</pre><br><br><p></p><p>printx()&nbsp;&lt;==OK</p><p>这次Java源码又变成什么样了呢？</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905193938259" alt=""><br></p><p style="text-align: center;">图15&nbsp; 进化版的test.groovy</p></td> </tr></tbody></table></div><br clear="ALL"><p>图15中，x也没有被定义成test的成员函数，而是在run的执行过程中，将x作为一个属性添加到test实例对象中了。然后在printx中，先获取这个属性。</p><div style="background:#F2F2F2;"><p>注意，Groovy的文档说 x = 1这种定义将使得x变成test的成员变量，但从反编译情况看，这是不对得.....</p></div><p>虽然printx可以访问x变量了，但是假如有其他脚本却无法访问x变量。因为它不是test的成员变量。</p><p>比如，我在测试目录下创建一个新的名为test1.groovy。这个test1将访问test.groovy中定义的printx函数：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905193959378" alt=""><br></p><p style="text-align: center;">图16&nbsp; test1.groovy使用test.groovy中的函数</p></td> </tr></tbody></table></div><br clear="ALL"><p>这种方法使得我们可以将代码分成模块来编写，<em>比如将公共的功能放到test.groovy中，然后使用公共功能的代码放到test1.groovy中</em>。</p><p>执行groovy test1.groovy，报错。说x找不到。这是因为x是在test的run函数动态加进去的。怎么办？</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 16347px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_21" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_21" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=21&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">import</span><span>&nbsp;groovy.transform.Field;&nbsp;&nbsp;&nbsp;</span><span class="comment">//必须要先import</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="annotation">@Field</span><span>&nbsp;x&nbsp;=&nbsp;</span><span class="number">1</span><span>&nbsp;&nbsp;&lt;==在x前面加上</span><span class="annotation">@Field</span><span>标注，这样，x就彻彻底底是test的成员变量了。&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">import groovy.transform.Field;   //必须要先import
@Field x = 1  &lt;==在x前面加上@Field标注，这样，x就彻彻底底是test的成员变量了。</pre><br><br><p></p><p>查看编译后的test.class文件，得到：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194014968" alt="">     </p>  <p><br></p><p style="text-align: center;">图17&nbsp; x现在是test类的成员变量了</p></td> </tr></tbody></table></div><br clear="ALL"><p>这个时候，test.groovy中的x就成了test类的成员函数了。如此，我们可以在script中定义那些需要输出给外部脚本或类使用的变量了！</p><p>&nbsp;</p><h4><a name="t23"></a>3.5.2&nbsp; 文件I/O操作</h4><p>本节介绍下Groovy的文件I/O操作。直接来看例子吧，虽然比Java看起来简单，但要理解起来其实比较难。尤其是当你要自己查SDK并编写代码的时候。</p><p>整体说来，Groovy的I/O操作是在原有Java I/O操作上进行了更为简单方便的封装，并且使用Closure来简化代码编写。主要封装了如下一些了类：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194032351" alt=""><br></p><p style="text-align: center;">图18&nbsp; Groovy File I/o常用类和SDK文档位置</p></td> </tr></tbody></table></div><br clear="ALL"><h5><a name="t24"></a>1.&nbsp; 读文件</h5><p>Groovy中，文件读操作简单到令人发指：</p><p>def targetFile = new File(文件名)&nbsp;&lt;==File对象还是要创建的。</p><p>然后打开http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/File.html</p><p>看看Groovy定义的API：</p><p>&nbsp;</p><p>1 读该文件中的每一行：eachLine的唯一参数是一个Closure。Closure的参数是文件每一行的内容</p><p>&nbsp;&nbsp; 其内部实现肯定是Groovy打开这个文件，然后读取文件的一行，然后调用Closure...</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 17508px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_22" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_22" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=22&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>targetFile.eachLine{&nbsp;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;StringoneLine&nbsp;-&gt;&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;printlnoneLine&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&lt;==是不是令人发指？？！&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;"> targetFile.eachLine{ 
   StringoneLine -&gt;
    printlnoneLine    
}  &lt;==是不是令人发指？？！</pre><br><br><p></p><p>2 直接得到文件内容</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 17727px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_23" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_23" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=23&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>targetFile.getBytes()&nbsp;&nbsp;&lt;==文件内容一次性读出，返回类型为</span><span class="keyword">byte</span><span>[]&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;"> targetFile.getBytes()  &lt;==文件内容一次性读出，返回类型为byte[]</pre><br><br><p></p><p>&nbsp;注意前面提到的getter和setter函数，这里可以直接使用<span style="color:red;">targetFile.bytes</span>&nbsp;&nbsp;&nbsp; //....</p><p>&nbsp;</p><p>3 使用InputStream.InputStream的SDK在</p><p>&nbsp; <span style="color:red;">http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/InputStream.html</span></p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 17970px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_24" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_24" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=24&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>def&nbsp;ism&nbsp;=&nbsp;&nbsp;targetFile.newInputStream()&nbsp;&nbsp;</span></span></li><li class=""><span><span class="comment">//操作ism，最后记得关掉</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>ism.close&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">def ism =  targetFile.newInputStream()
//操作ism，最后记得关掉
ism.close</pre><br><br><p></p><p>&nbsp;</p><p>4 使用闭包操作inputStream，以后在Gradle里会常看到这种搞法</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 18197px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_25" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_25" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=25&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>&nbsp;targetFile.withInputStream{&nbsp;ism&nbsp;-&gt;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;操作ism.&nbsp;不用close。Groovy会自动替你close&nbsp;&nbsp;</span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;"> targetFile.withInputStream{ ism -&gt;
   操作ism. 不用close。Groovy会自动替你close
}</pre><br><br><p></p><p>确实够简单，令人发指。我当年死活也没找到withInputStream是个啥意思。所以，请各位开发者牢记Groovy I/O操作相关类的SDK地址：</p><p></p><ul><li>java.io.File: <strong>http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/File.html</strong></li><li>java.io.InputStream: <strong>http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/InputStream.html &nbsp; &nbsp; &nbsp;</strong></li><li>java.io.OutputStream: <strong>http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/OutputStream.html</strong></li><li>java.io.Reader: <strong>http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/Reader.html</strong></li><li>java.io.Writer: <strong>http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/Writer.html</strong></li><li>java.nio.file.Path: <strong>http://docs.groovy-lang.org/latest/html/groovy-jdk/java/nio/file/Path.html</strong></li></ul><p></p><h5><a name="t25"></a>2.&nbsp; 写文件</h5><p>和读文件差不多。不再啰嗦。这里给个例子，告诉大家如何copy文件。</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 18660px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_26" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_26" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=26&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>def&nbsp;srcFile&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;File(源文件名)&nbsp;&nbsp;</span></span></li><li class=""><span>def&nbsp;targetFile&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;File(目标文件名)&nbsp;&nbsp;</span></span></li><li class="alt"><span>targetFile.withOutputStream{&nbsp;os-&gt;&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;srcFile.withInputStream{&nbsp;ins-&gt;&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os&nbsp;&lt;&lt;&nbsp;ins&nbsp;&nbsp;&nbsp;<span class="comment">//利用OutputStream的&lt;&lt;操作符重载，完成从inputstream到OutputStream</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//的输出</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">def srcFile = new File(源文件名)
def targetFile = new File(目标文件名)
targetFile.withOutputStream{ os-&gt;
  srcFile.withInputStream{ ins-&gt;
      os &lt;&lt; ins   //利用OutputStream的&lt;&lt;操作符重载，完成从inputstream到OutputStream
       //的输出
   }
}</pre><br><br><p></p><p>尼玛....关于OutputStream的&lt;&lt;操作符重载，查看SDK文档后可知：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194055193" alt=""><br></p><p style="text-align: center;">图19&nbsp; OutputStream的&lt;&lt;操作符重载</p></td> </tr></tbody></table></div><br clear="ALL"><p>再一次向极致简单致敬。但是，SDK恐怕是离不开手了...</p><p>&nbsp;</p><h4><a name="t26"></a>3.5.3&nbsp; XML操作</h4><p>除了I/O异常简单之外，Groovy中的XML操作也极致得很。Groovy中，XML的解析提供了和XPath类似的方法，名为GPath。这是一个类，提供相应API。关于XPath，请脑补https://en.wikipedia.org/wiki/XPath。</p><p>GPath功能包括：给个例子好了，来自Groovy官方文档。</p><p></p><div class="dp-highlighter bg_html"><div class="bar"><div class="tools"><b>[html]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 446px; top: 19487px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_27" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_27" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=27&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-xml"><li class="alt"><span><span>test.xml文件：&nbsp;&nbsp;</span></span></li><li class=""><span><span class="tag">&lt;</span><span class="tag-name">response</span><span>&nbsp;</span><span class="attribute">version-api</span><span>=</span><span class="attribute-value">"2.0"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">books</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">book</span><span>&nbsp;</span><span class="attribute">available</span><span>=</span><span class="attribute-value">"20"</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"1"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>Don&nbsp;Xijote</span><span class="tag">&lt;/</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">author</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"1"</span><span class="tag">&gt;</span><span>Manuel&nbsp;De&nbsp;Cervantes</span><span class="tag">&lt;/</span><span class="tag-name">author</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">book</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">book</span><span>&nbsp;</span><span class="attribute">available</span><span>=</span><span class="attribute-value">"14"</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"2"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>Catcher&nbsp;in&nbsp;the&nbsp;Rye</span><span class="tag">&lt;/</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">author</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"2"</span><span class="tag">&gt;</span><span>JD&nbsp;Salinger</span><span class="tag">&lt;/</span><span class="tag-name">author</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">book</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">book</span><span>&nbsp;</span><span class="attribute">available</span><span>=</span><span class="attribute-value">"13"</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"3"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>Alice&nbsp;in&nbsp;Wonderland</span><span class="tag">&lt;/</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">author</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"3"</span><span class="tag">&gt;</span><span>Lewis&nbsp;Carroll</span><span class="tag">&lt;/</span><span class="tag-name">author</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">book</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">book</span><span>&nbsp;</span><span class="attribute">available</span><span>=</span><span class="attribute-value">"5"</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"4"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>Don&nbsp;Xijote</span><span class="tag">&lt;/</span><span class="tag-name">title</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">author</span><span>&nbsp;</span><span class="attribute">id</span><span>=</span><span class="attribute-value">"4"</span><span class="tag">&gt;</span><span>Manuel&nbsp;De&nbsp;Cervantes</span><span class="tag">&lt;/</span><span class="tag-name">author</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">book</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">books</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">response</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="html" style="display: none;">test.xml文件：
&lt;response version-api="2.0"&gt;
       &lt;value&gt;
           &lt;books&gt;
               &lt;book available="20" id="1"&gt;
                   &lt;title&gt;Don Xijote&lt;/title&gt;
                   &lt;author id="1"&gt;Manuel De Cervantes&lt;/author&gt;
               &lt;/book&gt;
               &lt;book available="14" id="2"&gt;
                   &lt;title&gt;Catcher in the Rye&lt;/title&gt;
                  &lt;author id="2"&gt;JD Salinger&lt;/author&gt;
              &lt;/book&gt;
              &lt;book available="13" id="3"&gt;
                  &lt;title&gt;Alice in Wonderland&lt;/title&gt;
                  &lt;author id="3"&gt;Lewis Carroll&lt;/author&gt;
              &lt;/book&gt;
              &lt;book available="5" id="4"&gt;
                  &lt;title&gt;Don Xijote&lt;/title&gt;
                  &lt;author id="4"&gt;Manuel De Cervantes&lt;/author&gt;
              &lt;/book&gt;
           &lt;/books&gt;
      &lt;/value&gt;
   &lt;/response&gt;</pre><br><br><p></p><p><span style="color:#00B050;">l&nbsp;</span>现在来看怎么玩转GPath：</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 20048px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_28" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_28" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=28&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="comment">//第一步，创建XmlSlurper类</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>def&nbsp;xparser&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;XmlSlurper()&nbsp;&nbsp;</span></span></li><li class="alt"><span>def&nbsp;targetFile&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;File(</span><span class="string">"test.xml"</span><span>)&nbsp;&nbsp;</span></span></li><li class=""><span><span class="comment">//轰轰的GPath出场</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>GPathResult&nbsp;gpathResult&nbsp;=xparser.parse(targetFile)&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;</span></li><li class="alt"><span><span class="comment">//开始玩test.xml。现在我要访问id=4的book元素。</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="comment">//下面这种搞法，gpathResult代表根元素response。通过e1.e2.e3这种</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="comment">//格式就能访问到各级子元素....</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>def&nbsp;book4&nbsp;=&nbsp;gpathResult.value.books.book[<span class="number">3</span><span>]&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="comment">//得到book4的author元素</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>def&nbsp;author&nbsp;=&nbsp;book4.author&nbsp;&nbsp;</span></li><li class="alt"><span><span class="comment">//再来获取元素的属性和textvalue</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="keyword">assert</span><span>&nbsp;author.text()&nbsp;==&nbsp;</span><span class="string">'&nbsp;Manuel&nbsp;De&nbsp;Cervantes&nbsp;'</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>获取属性更直观&nbsp;&nbsp;</span></li><li class=""><span>author.<span class="annotation">@id</span><span>&nbsp;==&nbsp;</span><span class="string">'4'</span><span>&nbsp;或者&nbsp;author[</span><span class="string">'@id'</span><span>]&nbsp;==&nbsp;</span><span class="string">'4'</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>属性一般是字符串，可通过toInteger转换成整数&nbsp;&nbsp;</span></li><li class=""><span>author.<span class="annotation">@id</span><span>.toInteger()&nbsp;==&nbsp;</span><span class="number">4</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>好了。GPath就说到这。再看个例子。我在使用Gradle的时候有个需求，就是获取AndroidManifest.xml版本号（versionName）。有了GPath，一行代码搞定，请看：&nbsp;&nbsp;</span></li><li class=""><span>def&nbsp;androidManifest&nbsp;=&nbsp;newXmlSlurper().parse(<span class="string">"AndroidManifest.xml"</span><span>)&nbsp;&nbsp;</span></span></li><li class="alt"><span>println&nbsp;androidManifest[<span class="string">'@android:versionName'</span><span>]&nbsp;&nbsp;</span></span></li><li class=""><span>或者&nbsp;&nbsp;</span></li><li class="alt"><span>println&nbsp;androidManifest.@<span class="string">'android:versionName'</span><span>&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">//第一步，创建XmlSlurper类
def xparser = new XmlSlurper()
def targetFile = new File("test.xml")
//轰轰的GPath出场
GPathResult gpathResult =xparser.parse(targetFile)
 
//开始玩test.xml。现在我要访问id=4的book元素。
//下面这种搞法，gpathResult代表根元素response。通过e1.e2.e3这种
//格式就能访问到各级子元素....
def book4 = gpathResult.value.books.book[3]
//得到book4的author元素
def author = book4.author
//再来获取元素的属性和textvalue
assert author.text() == ' Manuel De Cervantes '
获取属性更直观
author.@id == '4' 或者 author['@id'] == '4'
属性一般是字符串，可通过toInteger转换成整数
author.@id.toInteger() == 4
好了。GPath就说到这。再看个例子。我在使用Gradle的时候有个需求，就是获取AndroidManifest.xml版本号（versionName）。有了GPath，一行代码搞定，请看：
def androidManifest = newXmlSlurper().parse("AndroidManifest.xml")
println androidManifest['@android:versionName']
或者
println androidManifest.@'android:versionName'</pre><br><br><p></p><h3><a name="t27"></a>3.6&nbsp; 更多</h3><p>作为一门语言，Groovy是复杂的，是需要深入学习和钻研的。一本厚书甚至都无法描述Groovy的方方面面。</p><p>Anyway，从使用角度看，尤其是又限定在Gradle这个领域内，能用到的都是Groovy中一些简单的知识。</p><h2><a name="t28"></a>四、Gradle介绍</h2><p>现在正式进入Gradle。Gradle是一个工具，同时它也是一个编程框架。前面也提到过，使用这个工具可以完成app的编译打包等工作。当然你也可以用它干其他的事情。</p><div style="background:#F2F2F2;"><p>Gradle是什么？学习它到什么地步就可以了？</p><p>----------------------------------------------------------------------------------------------------------</p><p><span style="color:#ff0000;">=====&gt;看待问题的时候，所站的角度非常重要。</span></p><p><span style="color:#ff0000;">--&gt;当你把Gradle当工具看的时候，我们只想着如何用好它。会写、写好配置脚本就OK</span></p><p><span style="color:#ff0000;">--&gt;当你把它当做编程框架看的时候，你可能需要学习很多更深入的内容。</span></p><p><span style="color:#ff0000;">另外，今天我们把它当工具看，明天因为需求发生变化，我们可能又得把它当编程框架看。</span></p><p><span style="color:#ff0000;"><span style="background-color: rgb(242, 242, 242);">----------------------------------------------------------------------------------------------------------</span></span></p></div><h3><a name="t29"></a>4.1&nbsp; Gradle开发环境部署</h3><p>Gradle的官网：http://gradle.org/</p><p>文档位置：<span style="color:red;">https://docs.gradle.org/current/release-notes</span>。其中的<strong><em><span style="color:red;">UserGuide</span></em></strong>和<strong><em><span style="color:red;">DSL Reference</span></em></strong>很关键。User Guide就是介绍Gradle的一本书，而DSLReference是Gradle API的说明。</p><p>以Ubuntu为例，下载Gradle：<em>http://gradle.org/gradle-download/</em>&nbsp; 选择Completedistribution和Binary only distribution都行。然后解压到指定目录。</p><p>最后，设置~/.bashrc，把Gradle加到PATH里，如图20所示：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194121511" alt=""><br></p><p style="text-align: center;">图20&nbsp; 配置Gradle到bashrc</p></td> </tr></tbody></table></div><br clear="ALL"><p>执行source ~/.bashrc，初始化环境。</p><p>执行gradle --version，如果成功运行就OK了。</p><p>注意，为什么说Gradle是一个编程框架？来看它提供的API文档：</p><p><em>https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html</em></p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194136650" alt=""><br></p><p style="text-align: center;">图21&nbsp; Project接口说明</p></td> </tr></tbody></table></div><br clear="ALL"><p>原来，我们编写所谓的编译脚本，其实就是玩Gradle的API....所以它从更底层意义上看，是一个编程框架！</p><p>既然是编程框架，我在讲解Gradle的时候，尽量会从API的角度来介绍。有些读者肯定会不耐烦，为嘛这么费事？</p><p>从我个人的经历来看：因为我从网上学习到的资料来看，几乎全是从脚本的角度来介绍Gradle，结果学习一通下来，只记住参数怎么配置，却不知道它们都是函数调用，都是严格对应相关API的。</p><p>而从API角度来看待Gradle的话，有了SDK文档，你就可以编程。编程是靠记住一行行代码来实现的吗？不是，是在你掌握大体流程，然后根据SDK+API来完成的！</p><p>其实，Gradle自己的User Guide也明确说了<span style="color:#0070C0;">：</span></p><p>Buildscripts are code</p><h3><a name="t30"></a>4.2&nbsp; 基本组件</h3><p>Gradle是一个框架，它定义一套自己的游戏规则。我们要玩转Gradle，必须要遵守它设计的规则。下面我们来讲讲Gradle的基本组件：</p><p>Gradle中，每一个待编译的工程都叫一个Project。每一个Project在构建的时候都包含一系列的Task。比如一个Android APK的编译可能包含：<em>Java源码编译Task、资源编译Task、JNI编译Task、lint检查Task、打包生成APK的Task、签名Task等</em>。</p><p>一个Project到底包含多少个Task，其实是由编译脚本指定的插件决定。插件是什么呢？插件就是用来定义Task，并具体执行这些Task的东西。</p><p>刚才说了，Gradle是一个框架，作为框架，它负责定义流程和规则。而具体的编译工作则是通过插件的方式来完成的。比如<em>编译Java有Java插件，编译Groovy有Groovy插件，编译Android APP有Android APP插件，编译Android Library有Android Library插件</em></p><p>好了。到现在为止，你知道Gradle中每一个待编译的工程都是一个Project，一个具体的编译过程是由一个一个的Task来定义和执行的。</p><h4><a name="t31"></a>4.2.1&nbsp; 一个重要的例子</h4><p>下面我们来看一个实际的例子。这个例子非常有代表意义。图22是一个名为posdevice的目录。这个目录里包含3个Android Library工程，2个Android APP工程。</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194157628" alt=""><br></p><p style="text-align: center;">图22 重要例子</p></td> </tr></tbody></table></div><br clear="ALL"><p>在图22的例子中：</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>CPosDeviceSdk、CPosSystemSdk、CPosSystemSdkxxxImpl是Android Library。其中，CPosSystemSdkxxxImpl依赖CPosSystemSdk</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>CPosDeviceServerApk和CPosSdkDemo是Android APP。这些App和SDK有依赖关系。CPosDeviceServerApk依赖CPosDeviceSdk，而CPosSdkDemo依赖所有的Sdk Library。</li></ul><p></p><p><span style="color:red;">请回答问题，在上面这个例子中，有多少个</span><span style="color:red;">Project</span><span style="color:red;">？</span></p><p><span style="color:red;">请回答问题，在上面这个例子中，有多少个</span><span style="color:red;">Project</span><span style="color:red;">？</span></p><p><span style="color:red;">请回答问题，在上面这个例子中，有多少个</span><span style="color:red;">Project</span><span style="color:red;">？</span></p><div style="background:#F2F2F2;"><p>答案是：每一个Library和每一个App都是单独的Project。根据Gradle的要求，每一个Project在其根目录下都需要有一个build.gradle。build.gradle文件就是该Project的编译脚本，类似于Makefile。</p></div><p>看起来好像很简单，但是请注意：posdevice虽然包含5个独立的Project，但是要独立编译他们的话，得：</p><p><span style="color:#00B050;">l&nbsp;</span>cd&nbsp; 某个Project的目录。比如 cd CPosDeviceSdk</p><p><span style="color:#00B050;">l&nbsp;</span>然后执行 gradle&nbsp; xxxx（xxx是任务的名字。对Android来说，assemble这个Task会生成最终的产物，所以gradleassemble）</p><p>这很麻烦啊，有10个独立Project，就得重复执行10次这样的命令。更有甚者，所谓的独立Project其实有依赖关系的。比如我们这个例子。</p><p>那么，我想在posdevice目录下，直接执行gradle assemble，是否能把这5个Project的东西都编译出来呢？</p><p>答案自然是可以。在Gradle中，这叫<em>Multi-Projects Build</em>。把posdevice改造成支持Gradle的Multi-Projects Build很容易，需要：</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>在posdevice下也添加一个<span style="color: red;">build.gradle</span>。这个build.gradle一般干得活是：配置其他子Project的。比如为子Project添加一些属性。这个build.gradle有没有都无所属。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>在posdevice下添加一个名为<span style="color: red;">settings.gradle</span>。这个文件很重要，名字必须是settings.gradle。它里边用来告诉Gradle，这个multiprojects包含多少个子Project。</li></ul><p></p><p>来看settings.gradle的内容，最关键的内容就是告诉Gradle这个multiprojects包含哪些子projects:</p><p>[settings.gradle]</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 23204px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_29" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_29" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=29&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="comment">//通过include函数，将子Project的名字（其文件夹名）包含进来</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>include&nbsp;&nbsp;<span class="string">'CPosSystemSdk'</span><span>&nbsp;,</span><span class="string">'CPosDeviceSdk'</span><span>&nbsp;,&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">'CPosSdkDemo'</span><span>,</span><span class="string">'CPosDeviceServerApk'</span><span>,</span><span class="string">'CPosSystemSdkWizarPosImpl'</span><span>&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">//通过include函数，将子Project的名字（其文件夹名）包含进来
include  'CPosSystemSdk' ,'CPosDeviceSdk' ,
       'CPosSdkDemo','CPosDeviceServerApk','CPosSystemSdkWizarPosImpl'</pre><br><br><p></p><p>&nbsp;</p><div style="background:#F2F2F2;"><p>强烈建议：</p><p>如果你确实只有一个Project需要编译，我也建议你在目录下添加一个settings.gradle。我们团队内部的所有单个Project都已经改成支持Multiple-Project Build了。改得方法就是添加settings.gradle，然后include对应的project名字。</p></div><p>另外，settings.gradle除了可以include外，还可以设置一些函数。这些函数会在gradle构建整个工程任务的时候执行，所以，可以在settings做一些初始化的工作。比如：我的settings.gradle的内容：</p><p>//定义一个名为initMinshengGradleEnvironment<span style="color:windowtext;">的函数。该函数内部完成一些初始化操作</span></p><p><span style="color:windowtext;">//</span><span style="color:windowtext;">比如创建特定的目录，设置特定的参数等</span></p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 23587px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_30" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_30" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=30&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>def&nbsp;initMinshengGradleEnvironment(){&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;println<span class="string">"initialize&nbsp;Minsheng&nbsp;Gradle&nbsp;Environment&nbsp;....."</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;......<span class="comment">//干一些special的私活....</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;println<span class="string">"initialize&nbsp;Minsheng&nbsp;Gradle&nbsp;Environment&nbsp;completes..."</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li><li class=""><span><span class="comment">//settings.gradle加载的时候，会执行initMinshengGradleEnvironment</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>initMinshengGradleEnvironment()&nbsp;&nbsp;</span></li><li class=""><span><span class="comment">//include也是一个函数：</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>include&nbsp;<span class="string">'CPosSystemSdk'</span><span>&nbsp;,&nbsp;</span><span class="string">'CPosDeviceSdk'</span><span>&nbsp;,&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">'CPosSdkDemo'</span><span>,</span><span class="string">'CPosDeviceServerApk'</span><span>,</span><span class="string">'CPosSystemSdkWizarPosImpl'</span><span>&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">def initMinshengGradleEnvironment(){
    println"initialize Minsheng Gradle Environment ....."
    ......//干一些special的私活....
    println"initialize Minsheng Gradle Environment completes..."
}
//settings.gradle加载的时候，会执行initMinshengGradleEnvironment
initMinshengGradleEnvironment()
//include也是一个函数：
include 'CPosSystemSdk' , 'CPosDeviceSdk' ,
      'CPosSdkDemo','CPosDeviceServerApk','CPosSystemSdkWizarPosImpl'</pre><br><br><p></p><h4><a name="t32"></a>4.2.2&nbsp; gradle命令介绍</h4><h5><a name="t33"></a>1.&nbsp; gradle projects查看工程信息</h5><p>到目前为止，我们了解了Gradle什么呢？</p><p><span style="color:#00B050;">l&nbsp;</span>每一个Project都必须设置一个build.gradle文件。至于其内容，我们留到后面再说。</p><p><span style="color:#00B050;">l&nbsp;</span>对于multi-projects build，需要在根目录下也放一个build.gradle，和一个settings.gradle。</p><p><span style="color:#00B050;">l&nbsp;</span>一个Project是由若干tasks来组成的，当gradlexxx的时候，实际上是要求gradle执行xxx任务。这个任务就能完成具体的工作。</p><p><span style="color:#00B050;">l&nbsp;</span>当然，具体的工作和不同的插件有关系。编译Java要使用Java插件，编译Android APP需要使用Android APP插件。这些我们都留待后续讨论</p><p>gradle提供一些方便命令来查看和Project，Task相关的信息。比如在posdevice中，我想看这个multi projects到底包含多少个子Project：</p><p>执行gradle projects，得到图23：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194216394" alt="">     </p>  <p style="text-align: center;"><br></p><p style="text-align: center;">图23&nbsp; gradle projects</p></td> </tr></tbody></table></div><br clear="ALL"><p>你看，multi projects的情况下，posdevice这个目录对应的build.gradle叫Root</p><p>&nbsp;Project，它包含5个子Project。</p><p>如果你修改settings.gradle，使得include只有一个参数，则gradle projects的子project也会变少，比如图24：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194231875" alt=""><br></p><p style="text-align: center;">图24&nbsp; 修改settings.gradle，使得只包含CPosSystemSdk工程</p></td> </tr></tbody></table></div><br clear="ALL"><h5><a name="t34"></a>2.&nbsp; gradle tasks查看任务信息</h5><p>查看了Project信息，这个还比较简单，直接看settings.gradle也知道。那么Project包含哪些Task信息，怎么看呢？图23,24中最后的输出也告诉你了，想看某个Project包含哪些Task信息，只要执行：</p><p><em>gradleproject-path:tasks</em>&nbsp;就行。注意，<em>project-path</em>是目录名，后面必须跟冒号。</p><p>对于Multi-project，在根目录中，需要指定你想看哪个poject的任务。不过你要是已经cd到某个Project的目录了，则不需指定Project-path。</p><p>来看图25：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194251964" alt=""><br></p><p style="text-align: center;">图25&nbsp; gradle CPosSystemSdk:tasks</p></td> </tr></tbody></table></div><br clear="ALL"><p>图25是gradleCPosSystemSdk:tasks的结果。</p><div style="background:#F2F2F2;"><p></p><ul><li>cd CPossystemSdk</li><li>gradle tasks 得到同样的结果</li></ul><p></p></div><p>CPosSystemSdk是一个Android Library工程，Android Library对应的插件定义了好多Task。每种插件定义的Task都不尽相同，这就是所谓的Domain Specific，需要我们对相关领域有比较多的了解。</p><p>这些都是后话，我们以后会详细介绍。</p><h5><a name="t35"></a>3.&nbsp; gradle task-name执行任务</h5><p>图25中列出了好多任务，这时候就可以通过 gradle 任务名来执行某个任务。这和make xxx很像。比如：</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>gradle clean是执行清理任务，和make clean类似。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>gradle properites用来查看所有属性信息。</li></ul><p></p><p><span style="color:red;">gradle tasks</span>会列出每个任务的描述，通过描述，我们大概能知道这些任务是干什么的.....。然后gradletask-name执行它就好。</p><p>这里要强调一点：Task和Task之间往往是有关系的，<em>这就是所谓的依赖关系。比如，assemble task就依赖其他task先执行，assemble才能完成最终的输出</em><span style="color:red;">。</span></p><p>依赖关系对我们使用gradle有什么意义呢？</p><p>如果知道Task之间的依赖关系，那么开发者就可以添加一些定制化的Task。比如我为assemble添加一个SpecialTest任务，并指定assemble依赖于SpecialTest。当assemble执行的时候，就会先处理完它依赖的task。自然，SpecialTest就会得到执行了...</p><p>大家先了解这么多，等后面介绍如何写gradle脚本的时候，这就是调用几个函数的事情，Nothing Special!</p><p>&nbsp;</p><h3><a name="t36"></a>4.3&nbsp; Gradle工作流程</h3><p>Gradle的工作流程其实蛮简单，用一个图26来表达：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194317170" alt=""><br></p><p style="text-align: center;">     图26&nbsp; Gradle工作流程</p></td> </tr></tbody></table></div><br clear="ALL"><p>图26告诉我们，Gradle工作包含三个阶段：</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>首先是初始化阶段。对我们前面的multi-project build而言，就是执行settings.gradle</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>Initiliazation phase的下一个阶段是Configration阶段。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>Configration阶段的目标是解析每个project中的build.gradle。比如multi-project build例子中，解析每个子目录中的build.gradle。在这两个阶段之间，我们可以加一些定制化的Hook。这当然是通过API来添加的。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>Configuration阶段完了后，整个build的project以及内部的Task关系就确定了。恩？前面说过，一个Project包含很多Task，每个Task之间有依赖关系。Configuration会建立一个有向图来描述Task之间的依赖关系。所以，我们可以添加一个HOOK，即当Task关系图建立好后，执行一些操作。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>最后一个阶段就是执行任务了。当然，任务执行完后，我们还可以加Hook。</li></ul><p></p><p>下面展示一下我按图26为posdevice项目添加的Hook，它的执行结果：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194338602" alt=""><br></p><p style="text-align: center;">图26&nbsp; 加了Hook后的执行结果</p></td> </tr></tbody></table></div><br clear="ALL"><p>我在：</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>settings.gradle加了一个输出。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>在posdevice的build.gradle加了图25中的beforeProject函数。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>在CPosSystemSdk加了taskGraph whenReady函数和buidFinished函数。</li></ul><p></p><p>好了，Hook的代码怎么写，估计你很好奇，而且肯定会埋汰，搞毛这么就还没告诉我怎么写Gradle。马上了！</p><p>最后，关于Gradle的工作流程，你只要记住：</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>Gradle有一个初始化流程，这个时候settings.gradle会执行。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>在配置阶段，每个Project都会被解析，其内部的任务也会被添加到一个有向图里，用于解决执行过程中的依赖关系。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>然后才是执行阶段。你在gradle xxx中指定什么任务，gradle就会将这个xxx任务链上的所有任务全部按依赖顺序执行一遍！</li></ul><p></p><p>下面来告诉你怎么写代码！</p><h3><a name="t37"></a>4.4&nbsp; Gradle编程模型及API实例详解</h3><p>希望你在进入此节之前，一定花时间把前面内容看一遍！！！</p><p><em>https://docs.gradle.org/current/dsl/</em>&nbsp; &lt;==这个文档很重要</p><p>Gradle基于Groovy，Groovy又基于Java。所以，Gradle执行的时候和Groovy一样，会把脚本转换成Java对象。Gradle主要有三种对象，这三种对象和三种不同的脚本文件对应，在gradle执行的时候，会将脚本转换成对应的对端：</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>Gradle对象：当我们执行gradle xxx或者什么的时候，gradle会从默认的配置脚本中构造出一个Gradle对象。在整个执行过程中，只有这么一个对象。Gradle对象的数据类型就是Gradle。我们一般很少去定制这个默认的配置脚本。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>Project对象：每一个build.gradle会转换成一个Project对象。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>Settings对象：显然，每一个settings.gradle都会转换成一个Settings对象。</li></ul><p></p><div style="background:#F2F2F2;"><p>注意，对于其他gradle文件，除非定义了class，否则会转换成一个实现了Script接口的对象。这一点和3.5节中Groovy的脚本类相似</p></div><p>当我们执行gradle的时候，gradle首先是按顺序解析各个gradle文件。这里边就有所所谓的生命周期的问题，即先解析谁，后解析谁。图27是Gradle文档中对生命周期的介绍：结合上一节的内容，相信大家都能看明白了。现在只需要看红框里的内容：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194405209" alt=""><br></p><p style="text-align: center;">图27&nbsp; Gradle对LifeCycle的介绍</p></td> </tr></tbody></table></div><br clear="ALL"><h4><a name="t38"></a>4.4.1&nbsp; Gradle对象</h4><p>我们先来看Gradle对象，它有哪些属性呢？如图28所示：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194421970" alt=""><br></p><p style="text-align: center;">图28&nbsp; Gradle的属性</p></td> </tr></tbody></table></div><br clear="ALL"><p>我在posdevice build.gradle中和settings.gradle中分别加了如下输出：</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 27737px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_31" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_31" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=31&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="comment">//在settings.gradle中，则输出"In&nbsp;settings,gradle&nbsp;id&nbsp;is"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>println&nbsp;<span class="string">"In&nbsp;posdevice,&nbsp;gradle&nbsp;id&nbsp;is&nbsp;"</span><span>&nbsp;+gradle.hashCode()&nbsp;&nbsp;</span></span></li><li class="alt"><span>println&nbsp;<span class="string">"Home&nbsp;Dir:"</span><span>&nbsp;+&nbsp;gradle.gradleHomeDir&nbsp;&nbsp;</span></span></li><li class=""><span>println&nbsp;<span class="string">"User&nbsp;Home&nbsp;Dir:"</span><span>&nbsp;+&nbsp;gradle.gradleUserHomeDir&nbsp;&nbsp;</span></span></li><li class="alt"><span>println&nbsp;<span class="string">"Parent:&nbsp;"</span><span>&nbsp;+&nbsp;gradle.parent&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">//在settings.gradle中，则输出"In settings,gradle id is"
println "In posdevice, gradle id is " +gradle.hashCode()
println "Home Dir:" + gradle.gradleHomeDir
println "User Home Dir:" + gradle.gradleUserHomeDir
println "Parent: " + gradle.parent</pre><br><br><p></p><p>得到结果如图29所示：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194440047" alt=""><br></p><p style="text-align: center;">图29&nbsp; gradle示例</p></td> </tr></tbody></table></div><br clear="ALL"><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>你看，在settings.gradle和posdevice build.gradle中，我们得到的gradle实例对象的hashCode是一样的（都是791279786）。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>HomeDir是我在哪个目录存储的gradle可执行程序。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>User Home Dir：是gradle自己设置的目录，里边存储了一些配置文件，以及编译过程中的缓存文件，生成的类文件，编译中依赖的插件等等。</li></ul><p></p><p>Gradle的函数接口在文档中也有。</p><h4><a name="t39"></a>4.4.2&nbsp; Project对象</h4><p>每一个build.gradle文件都会转换成一个Project对象。在Gradle术语中，Project对象对应的是<em>BuildScript</em>。</p><p>Project包含若干Tasks。另外，由于Project对应具体的工程，所以需要为Project加载所需要的插件，比如为Java工程加载Java插件。其实，一个Project包含多少Task往往是插件决定的。</p><p>所以，在Project中，我们要：</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span><span style="color: windowtext;">加载插件。</span></li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span><span style="color: windowtext;">不同插件有不同的行话，即不同的配置。我们要在</span><span style="color: windowtext;">Project</span><span style="color: windowtext;">中配置好，这样插件就知道从哪里读取源文件等</span></li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span><span style="color: windowtext;">设置属性。</span></li></ul><p></p><h5><a name="t40"></a>1.&nbsp; 加载插件</h5><p>Project的API位于<em>https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html</em>。加载插件是调用它的apply函数.apply其实是Project实现的PluginAware接口定义的：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194503216" alt=""><br></p><p style="text-align: center;">图30&nbsp; apply函数</p></td> </tr></tbody></table></div><br clear="ALL"><p>来看代码：</p><p>[apply函数的用法]</p><p>apply是一个函数，此处调用的是图30中最后一个apply函数。注意，Groovy支持</p><p>函数调用的时候通过&nbsp; 参数名1:参数值2，参数名2：参数值2 的方式来传递参数</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 28888px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_32" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_32" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=32&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>apply&nbsp;plugin:&nbsp;</span><span class="string">'com.android.library'</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&lt;==如果是编译Library，则加载此插件&nbsp;&nbsp;</span></span></li><li class=""><span>apply&nbsp;plugin:&nbsp;<span class="string">'com.android.application'</span><span>&nbsp;&nbsp;&lt;==如果是编译Android&nbsp;APP，则加载此插件&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">apply plugin: 'com.android.library'    &lt;==如果是编译Library，则加载此插件
apply plugin: 'com.android.application'  &lt;==如果是编译Android APP，则加载此插件</pre><br><br><p></p><p>除了加载二进制的插件（上面的插件其实都是下载了对应的jar包，这也是通常意义上我们所理解的插件），还可以加载一个gradle文件。为什么要加载gradle文件呢？</p><p>其实这和代码的模块划分有关。一般而言，我会把一些通用的函数放到一个名叫utils.gradle文件里。然后在其他工程的build.gradle来加载这个utils.gradle。这样，通过一些处理，我就可以调用utils.gradle中定义的函数了。</p><p>加载utils.gradle插件的代码如下：</p><p>utils.gradle是我封装的一个gradle脚本，里边定义了一些方便函数，比如读取AndroidManifest.xml中</p><p>的versionName，或者是copy jar包/APK包到指定的目录</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 29227px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_33" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_33" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=33&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>apply&nbsp;from:&nbsp;rootProject.getRootDir().getAbsolutePath()&nbsp;+&nbsp;</span><span class="string">"/utils.gradle"</span><span>&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">apply from: rootProject.getRootDir().getAbsolutePath() + "/utils.gradle"</pre><br><br><p></p><p>也是使用apply的最后一个函数。那么，apply最后一个函数到底支持哪些参数呢？还是得看图31中的API说明：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194525120" alt="">     </p>  <p style="text-align: center;"><br></p><p style="text-align: center;">图31&nbsp; apply API说明</p></td> </tr></tbody></table></div><br clear="ALL"><p>我这里不遗余力的列出API图片，就是希望大家在写脚本的时候，碰到不会的，一定要去查看API文档！</p><h5><a name="t41"></a>2.&nbsp; 设置属性</h5><p>如果是单个脚本，则不需要考虑属性的跨脚本传播，但是Gradle往往包含不止一个build.gradle文件，比如我设置的utils.gradle，settings.gradle。如何在多个脚本中设置属性呢？</p><p>Gradle提供了一种名为extra property的方法。<em>extra property</em>是额外属性的意思，在第一次定义该属性的时候需要通过ext前缀来标示它是一个额外的属性。定义好之后，后面的存取就不需要ext前缀了。ext属性支持Project和Gradle对象。即Project和Gradle对象都可以设置ext属性</p><p>举个例子：</p><p>我在settings.gradle中想为Gradle对象设置一些外置属性，所以在initMinshengGradleEnvironment函数中</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 30026px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_34" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_34" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=34&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>def&nbsp;initMinshengGradleEnvironment(){&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//属性值从local.properites中读取</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;Propertiesproperties&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;Properties()&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;FilepropertyFile&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;File(rootDir.getAbsolutePath()&nbsp;+</span><span class="string">"/local.properties"</span><span>)&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;properties.load(propertyFile.newDataInputStream())&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//gradle就是gradle对象。它默认是Settings和Project的成员变量。可直接获取</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;<span class="comment">//ext前缀，表明操作的是外置属性。api是一个新的属性名。前面说过，只在</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;<span class="comment">//第一次定义或者设置它的时候需要ext前缀</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;gradle.ext.api&nbsp;=properties.getProperty(<span class="string">'sdk.api'</span><span>)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;println&nbsp;gradle.api&nbsp;&nbsp;<span class="comment">//再次存取api的时候，就不需要ext前缀了</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;......&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">def initMinshengGradleEnvironment(){
    //属性值从local.properites中读取
    Propertiesproperties = new Properties()
    FilepropertyFile = new File(rootDir.getAbsolutePath() +"/local.properties")
   properties.load(propertyFile.newDataInputStream())
    //gradle就是gradle对象。它默认是Settings和Project的成员变量。可直接获取
   //ext前缀，表明操作的是外置属性。api是一个新的属性名。前面说过，只在
   //第一次定义或者设置它的时候需要ext前缀
    gradle.ext.api =properties.getProperty('sdk.api')
   
    println gradle.api  //再次存取api的时候，就不需要ext前缀了
    ......
    }</pre><br><br><p></p><p>再来一个例子强化一下：</p><p>我在utils.gradle中定义了一些函数，然后想在其他build.gradle中调用这些函数。那该怎么做呢？</p><p>[utils.gradle]</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 30459px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_35" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_35" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=35&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="comment">//utils.gradle中定义了一个获取AndroidManifests.xmlversionName的函数</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>def&nbsp;&nbsp;getVersionNameAdvanced(){&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;下面这行代码中的project是谁？&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;defxmlFile&nbsp;=&nbsp;project.file(<span class="string">"AndroidManifest.xml"</span><span>)&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;defrootManifest&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;XmlSlurper().parse(xmlFile)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;returnrootManifest[<span class="string">'@android:versionName'</span><span>]&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li><li class=""><span><span class="comment">//现在，想把这个API输出到各个Project。由于这个utils.gradle会被每一个Project&nbsp;Apply，所以</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="comment">//我可以把getVersionNameAdvanced定义成一个closure，然后赋值到一个外部属性</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;下面的ext是谁的ext？&nbsp;&nbsp;</span></li><li class="alt"><span>ext{&nbsp;<span class="comment">//此段花括号中代码是闭包</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//除了ext.xxx=value这种定义方法外，还可以使用ext{}这种书写方法。</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//ext{}不是ext(Closure)对应的函数调用。但是ext{}中的{}确实是闭包。</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;getVersionNameAdvanced&nbsp;=&nbsp;<span class="keyword">this</span><span>.&amp;getVersionNameAdvanced&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">//utils.gradle中定义了一个获取AndroidManifests.xmlversionName的函数
def  getVersionNameAdvanced(){
  下面这行代码中的project是谁？
   defxmlFile = project.file("AndroidManifest.xml")
   defrootManifest = new XmlSlurper().parse(xmlFile)
   returnrootManifest['@android:versionName']  
}
//现在，想把这个API输出到各个Project。由于这个utils.gradle会被每一个Project Apply，所以
//我可以把getVersionNameAdvanced定义成一个closure，然后赋值到一个外部属性
  下面的ext是谁的ext？
ext{ //此段花括号中代码是闭包
    //除了ext.xxx=value这种定义方法外，还可以使用ext{}这种书写方法。
    //ext{}不是ext(Closure)对应的函数调用。但是ext{}中的{}确实是闭包。
    getVersionNameAdvanced = this.&amp;getVersionNameAdvanced
 }</pre><br><br><p></p><p>上面代码中有两个问题：</p><p></p><ul><li><span style="color:#ff0000;">&nbsp; project是谁？</span></li><li><span style="color:#ff0000;">&nbsp; ext是谁的ext？</span></li></ul><p></p><p>上面两个问题比较关键，我也是花了很长时间才搞清楚。这两个问题归结到一起，其实就是：</p><p>加载utils.gradle的Project对象和utils.gradle本身所代表的Script对象到底有什么关系？</p><p>我们在Groovy中也讲过怎么在一个Script中import另外一个Script中定义的类或者函数（见<em>3.5 脚本类、文件I/O和XML操作一节</em>）。在Gradle中，这一块的处理比Groovy要复杂，具体怎么搞我还没完全弄清楚，但是Project和utils.gradle对于的Script的对象的关系是：</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>当一个Project apply一个gradle文件的时候，这个gradle文件会转换成一个Script对象。这个，相信大家都已经知道了。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>Script中有一个delegate对象，这个delegate默认是加载（即调用apply）它的Project对象。但是，在apply函数中，有一个from参数，还有一个to参数（参考<em>图31</em>）。通过to参数，你可以把delegate对象指定为别的东西。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>delegate对象是什么意思？当你在Script中操作一些不是Script自己定义的变量，或者函数时候，gradle会到Script的delegate对象去找，看看有没有定义这些变量或函数。</li></ul><p></p><p>现在你知道问题1,2和答案了：</p><div style="background:#F2F2F2;"><p></p><ul><li>问题1：project就是加载utils.gradle的project。由于posdevice有5个project，所以utils.gradle会分别加载到5个project中。所以，getVersionNameAdvanced才不用区分到底是哪个project。反正一个project有一个utils.gradle对应的Script。</li><li>问题2：ext：自然就是Project对应的ext了。此处为Project添加了一些closure。那么，在Project中就可以调用getVersionNameAdvanced函数了</li></ul><p></p></div><p>比如：我在posdevice每个build.gradle中都有如下的代码：</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 31376px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_36" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_36" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=36&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>tasks.getByName(</span><span class="string">"assemble"</span><span>){&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;it.doLast{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;println&nbsp;<span class="string">"$project.name:&nbsp;After&nbsp;assemble,&nbsp;jar&nbsp;libs&nbsp;are&nbsp;copied&nbsp;tolocal&nbsp;repository"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;copyOutput(<span class="keyword">true</span><span>)&nbsp;&nbsp;</span><span class="comment">//copyOutput是utils.gradle输出的closure</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">tasks.getByName("assemble"){
   it.doLast{
       println "$project.name: After assemble, jar libs are copied tolocal repository"
        copyOutput(true)  //copyOutput是utils.gradle输出的closure
     }
}</pre><br><br><p></p><p>通过这种方式，我将一些常用的函数放到utils.gradle中，然后为加载它的Project设置ext属性。最后，Project中就可以调用这种赋值函数了！</p><div style="background:#F2F2F2;"><p>注意：此处我研究的还不是很深，而且我个人感觉：</p><p>1&nbsp; 在Java和Groovy中：我们会把常用的函数放到一个辅助类和公共类中，然后在别的地方import并调用它们。</p><p>2&nbsp; 但是在Gradle，更正规的方法是在xxx.gradle中定义插件。然后通过添加Task的方式来完成工作。gradle的user guide有详细介绍如何实现自己的插件。</p></div><h5><a name="t42"></a>3.&nbsp; Task介绍</h5><p>Task是Gradle中的一种数据类型，它代表了一些要执行或者要干的工作。不同的插件可以添加不同的Task。每一个Task都需要和一个Project关联。</p><p>Task的API文档位于<em>https://docs.gradle.org/current/dsl/org.gradle.api.Task.html</em>。关于Task，我这里简单介绍下build.gradle中怎么写它，以及Task中一些常见的类型</p><p>关于Task。来看下面的例子：</p><p>[build.gradle]</p><p>/</p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 31957px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_37" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_37" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=37&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>/Task是和Project关联的，所以，我们要利用Project的task函数来创建一个Task&nbsp;&nbsp;</span></span></li><li class=""><span>task&nbsp;myTask&nbsp;&nbsp;&lt;==myTask是新建Task的名字&nbsp;&nbsp;</span></li><li class="alt"><span>task&nbsp;myTask&nbsp;{&nbsp;configure&nbsp;closure&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>task&nbsp;myType&nbsp;&lt;&lt;&nbsp;{&nbsp;task&nbsp;action&nbsp;}&nbsp;&lt;==注意，&lt;&lt;符号是doLast的缩写&nbsp;&nbsp;</span></li><li class="alt"><span>task&nbsp;myTask(type:&nbsp;SomeType)&nbsp;&nbsp;</span></li><li class=""><span>task&nbsp;myTask(type:&nbsp;SomeType)&nbsp;{&nbsp;configure&nbsp;closure&nbsp;}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">/Task是和Project关联的，所以，我们要利用Project的task函数来创建一个Task
task myTask  &lt;==myTask是新建Task的名字
task myTask { configure closure }
task myType &lt;&lt; { task action } &lt;==注意，&lt;&lt;符号是doLast的缩写
task myTask(type: SomeType)
task myTask(type: SomeType) { configure closure }</pre><br><p></p><p>上述代码中都用了Project的一个函数，名为task，注意：</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>一个Task包含若干Action。所以，Task有doFirst和doLast两个函数，用于添加需要最先执行的Action和需要和需要最后执行的Action。Action就是一个闭包。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>Task创建的时候可以指定Type，通过<em>type:名字</em>表达。这是什么意思呢？其实就是告诉Gradle，这个新建的Task对象会从哪个基类Task派生。比如，Gradle本身提供了一些通用的Task，最常见的有Copy 任务。Copy是Gradle中的一个类。当我们：<em>task myTask(type:Copy)</em>的时候，创建的Task就是一个Copy Task。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>当我们使用 taskmyTask{ xxx}的时候。花括号是一个closure。这会导致gradle在创建这个Task之后，返回给用户之前，会先执行closure的内容。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>当我们使用taskmyTask &lt;&lt; {xxx}的时候，我们创建了一个Task对象，同时把closure做为一个action加到这个Task的action队列中，并且告诉它“最后才执行这个closure”（<em>注意，&lt;&lt;符号是doLast的代表</em>）。</li></ul><p></p><p>图32是Project中关于task函数说明：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194548323" alt="">     </p>  <p style="text-align: center;"><br></p><p style="text-align: center;">图32&nbsp; Project中task函数</p></td> </tr></tbody></table></div><br clear="ALL"><p>陆陆续续讲了这么些内容，我自己感觉都有点烦了。是得，Gradle用一整本书来讲都嫌不够呢。</p><p>anyway，到目前为止，我介绍的都是一些比较基础的东西，还不是特别多。但是后续例子该涉及到的知识点都有了。下面我们直接上例子。这里有两个例子：</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>posdevice的例子</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>另外一个是单个project的例子</li></ul><p></p><h4><a name="t43"></a>4.4.3&nbsp; posdevice实例</h4><p>现在正是开始通过例子来介绍怎么玩gradle。这里要特别强调一点，根据Gradle的哲学。gradle文件中包含一些所谓的Script Block（<em>姑且这么称它</em>）。ScriptBlock作用是让我们来配置相关的信息。不同的SB有不同的需要配置的东西。这也是我最早说的行话。比如，源码对应的SB，就需要我们配置源码在哪个文件夹里。关于SB，我们后面将见识到！</p><p>posdevice是一个multi project。下面包含5个Project。对于这种Project，请大家回想下我们该创建哪些文件？</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>settings.gradle是必不可少的</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>根目录下的build.gradle。这个我们没讲过，因为posdevice的根目录本身不包含代码，而是包含其他5个子project。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>每个project目录下包含对于的build.gradle</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>另外，我把常用的函数封装到一个名为utils.gradle的脚本里了。</li></ul><p></p><p>马上一个一个来看它们。</p><h5><a name="t44"></a>1.&nbsp; utils.gradle</h5><p>utils.gradle是我自己加的，为我们团队特意加了一些常见函数。主要代码如下：</p><p>[utils.gradle]</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 33090px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_38" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_38" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=38&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="keyword">import</span><span>&nbsp;groovy.util.XmlSlurper&nbsp;&nbsp;</span><span class="comment">//解析XML时候要引入这个groovy的package</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;</span></li><li class="alt"><span>def&nbsp;copyFile(String&nbsp;srcFile,dstFile){&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;......<span class="comment">//拷贝文件函数，用于将最后的生成物拷贝到指定的目录</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li><li class=""><span>def&nbsp;rmFile(String&nbsp;targetFile){&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;.....<span class="comment">//删除指定目录中的文件</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;</span></li><li class=""><span>def&nbsp;cleanOutput(<span class="keyword">boolean</span><span>&nbsp;bJar&nbsp;=&nbsp;</span><span class="keyword">true</span><span>){&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;....<span class="comment">//clean的时候清理</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;</span></li><li class=""><span>def&nbsp;copyOutput(<span class="keyword">boolean</span><span>&nbsp;bJar&nbsp;=&nbsp;</span><span class="keyword">true</span><span>){&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;....<span class="comment">//copyOutput内部会调用copyFile完成一次build的产出物拷贝</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;</span></li><li class=""><span>def&nbsp;getVersionNameAdvanced(){<span class="comment">//老朋友</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;defxmlFile&nbsp;=&nbsp;project.file(<span class="string">"AndroidManifest.xml"</span><span>)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;defrootManifest&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;XmlSlurper().parse(xmlFile)&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;returnrootManifest[<span class="string">'@android:versionName'</span><span>]&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li><li class=""><span>}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;</span></li><li class=""><span><span class="comment">//对于android&nbsp;library编译，我会disable所有的debug编译任务</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>def&nbsp;disableDebugBuild(){&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;<span class="comment">//project.tasks包含了所有的tasks，下面的findAll是寻找那些名字中带debug的Task。</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;<span class="comment">//返回值保存到targetTasks容器中</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;def&nbsp;targetTasks&nbsp;=&nbsp;project.tasks.findAll{task&nbsp;-&gt;&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;task.name.contains(<span class="string">"Debug"</span><span>)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;<span class="comment">//对满足条件的task，设置它为disable。如此这般，这个Task就不会被执行</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;targetTasks.each{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;println<span class="string">"disable&nbsp;debug&nbsp;task&nbsp;&nbsp;:${it.name}"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;it.setEnabled&nbsp;<span class="keyword">false</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>}&nbsp;&nbsp;</span></li><li class="alt"><span><span class="comment">//将函数设置为extra属性中去，这样，加载utils.gradle的Project就能调用此文件中定义的函数了</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>ext{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;copyFile=&nbsp;<span class="keyword">this</span><span>.&amp;copyFile&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;rmFile&nbsp;=<span class="keyword">this</span><span>.&amp;rmFile&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;cleanOutput&nbsp;=&nbsp;<span class="keyword">this</span><span>.&amp;cleanOutput&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;copyOutput&nbsp;=&nbsp;<span class="keyword">this</span><span>.&amp;copyOutput&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;getVersionNameAdvanced&nbsp;=&nbsp;<span class="keyword">this</span><span>.&amp;getVersionNameAdvanced&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;disableDebugBuild&nbsp;=&nbsp;<span class="keyword">this</span><span>.&amp;disableDebugBuild&nbsp;&nbsp;</span></span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">import groovy.util.XmlSlurper  //解析XML时候要引入这个groovy的package
 
def copyFile(String srcFile,dstFile){
     ......//拷贝文件函数，用于将最后的生成物拷贝到指定的目录
}
def rmFile(String targetFile){
    .....//删除指定目录中的文件
}
 
def cleanOutput(boolean bJar = true){
    ....//clean的时候清理
}
 
def copyOutput(boolean bJar = true){
    ....//copyOutput内部会调用copyFile完成一次build的产出物拷贝
}
 
def getVersionNameAdvanced(){//老朋友
   defxmlFile = project.file("AndroidManifest.xml")
   defrootManifest = new XmlSlurper().parse(xmlFile)
   returnrootManifest['@android:versionName']  
}
 
//对于android library编译，我会disable所有的debug编译任务
def disableDebugBuild(){
  //project.tasks包含了所有的tasks，下面的findAll是寻找那些名字中带debug的Task。
  //返回值保存到targetTasks容器中
  def targetTasks = project.tasks.findAll{task -&gt;
     task.name.contains("Debug")
  }
  //对满足条件的task，设置它为disable。如此这般，这个Task就不会被执行
 targetTasks.each{
     println"disable debug task  :${it.name}"
    it.setEnabled false
  }
}
//将函数设置为extra属性中去，这样，加载utils.gradle的Project就能调用此文件中定义的函数了
ext{
    copyFile= this.&amp;copyFile
    rmFile =this.&amp;rmFile
   cleanOutput = this.&amp;cleanOutput
   copyOutput = this.&amp;copyOutput
   getVersionNameAdvanced = this.&amp;getVersionNameAdvanced
   disableDebugBuild = this.&amp;disableDebugBuild
}</pre><br><br><p></p><p>图33展示了被disable的Debug任务的部分信息：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194607997" alt=""><br></p><p style="text-align: center;">图33&nbsp; disable的Debug Task信息</p></td> </tr></tbody></table></div><br clear="ALL"><h5><a name="t45"></a>2.&nbsp; settings.gradle</h5><p>这个文件中我们该干什么？调用include把需要包含的子Project加进来。代码如下：</p><p>[settings.gradle]</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 34217px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_39" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_39" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=39&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="comment">/*我们团队内部建立的编译环境初始化函数</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;这个函数的目的是</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;1&nbsp;&nbsp;解析一个名为local.properties的文件，读取AndroidSDK和NDK的路径</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;2&nbsp;&nbsp;获取最终产出物目录的路径。这样，编译完的apk或者jar包将拷贝到这个最终产出物目录中</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;3&nbsp;获取Android&nbsp;SDK指定编译的版本</span>&nbsp;</span></li><li class=""><span><span class="comment">*/</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>def&nbsp;initMinshengGradleEnvironment(){&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;println<span class="string">"initialize&nbsp;Minsheng&nbsp;Gradle&nbsp;Environment&nbsp;....."</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;Properties&nbsp;properties&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;Properties()&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;<span class="comment">//local.properites也放在posdevice目录下</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;FilepropertyFile&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;File(rootDir.getAbsolutePath()+&nbsp;</span><span class="string">"/local.properties"</span><span>)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;properties.load(propertyFile.newDataInputStream())&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/*</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;根据Project、Gradle生命周期的介绍，settings对象的创建位于具体Project创建之前</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;而Gradle底对象已经创建好了。所以，我们把local.properties的信息读出来后，通过</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;extra属性的方式设置到gradle对象中</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;而具体Project在执行的时候，就可以直接从gradle对象中得到这些属性了！</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;gradle.ext.api&nbsp;=properties.getProperty(<span class="string">'sdk.api'</span><span>)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;gradle.ext.sdkDir&nbsp;=properties.getProperty(<span class="string">'sdk.dir'</span><span>)&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gradle.ext.ndkDir&nbsp;=properties.getProperty(<span class="string">'ndk.dir'</span><span>)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gradle.ext.localDir&nbsp;=properties.getProperty(<span class="string">'local.dir'</span><span>)&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//指定debugkeystore文件的位置，debug版apk签名的时候会用到</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;gradle.ext.debugKeystore=&nbsp;properties.getProperty(<span class="string">'debug.keystore'</span><span>)&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;......&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;println<span class="string">"initialize&nbsp;Minsheng&nbsp;Gradle&nbsp;Environment&nbsp;completes..."</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li><li class=""><span><span class="comment">//初始化</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>initMinshengGradleEnvironment()&nbsp;&nbsp;</span></li><li class=""><span><span class="comment">//添加子Project信息</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>include&nbsp;<span class="string">'CPosSystemSdk'</span><span>&nbsp;,&nbsp;</span><span class="string">'CPosDeviceSdk'</span><span>&nbsp;,</span><span class="string">'CPosSdkDemo'</span><span>,</span><span class="string">'CPosDeviceServerApk'</span><span>,&nbsp;</span><span class="string">'CPosSystemSdkWizarPosImpl'</span><span>&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">/*我们团队内部建立的编译环境初始化函数
  这个函数的目的是
  1  解析一个名为local.properties的文件，读取AndroidSDK和NDK的路径
  2  获取最终产出物目录的路径。这样，编译完的apk或者jar包将拷贝到这个最终产出物目录中
  3 获取Android SDK指定编译的版本
*/
def initMinshengGradleEnvironment(){
    println"initialize Minsheng Gradle Environment ....."
   Properties properties = new Properties()
   //local.properites也放在posdevice目录下
    FilepropertyFile = new File(rootDir.getAbsolutePath()+ "/local.properties")
   properties.load(propertyFile.newDataInputStream())
    /*
      根据Project、Gradle生命周期的介绍，settings对象的创建位于具体Project创建之前
      而Gradle底对象已经创建好了。所以，我们把local.properties的信息读出来后，通过
     extra属性的方式设置到gradle对象中
      而具体Project在执行的时候，就可以直接从gradle对象中得到这些属性了！
    */
    gradle.ext.api =properties.getProperty('sdk.api')
    gradle.ext.sdkDir =properties.getProperty('sdk.dir')
     gradle.ext.ndkDir =properties.getProperty('ndk.dir')
     gradle.ext.localDir =properties.getProperty('local.dir')
    //指定debugkeystore文件的位置，debug版apk签名的时候会用到
    gradle.ext.debugKeystore= properties.getProperty('debug.keystore')
     ......
    println"initialize Minsheng Gradle Environment completes..."
}
//初始化
initMinshengGradleEnvironment()
//添加子Project信息
include 'CPosSystemSdk' , 'CPosDeviceSdk' ,'CPosSdkDemo','CPosDeviceServerApk', 'CPosSystemSdkWizarPosImpl'</pre><br><br><p></p><p>注意，对于Android来说，local.properties文件是必须的，它的内容如下：</p><p>[local.properties]</p><p></p><div class="dp-highlighter bg_plain"><div class="bar"><div class="tools"><b>[plain]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 448px; top: 34948px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_40" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_40" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=40&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1"><li class="alt"><span><span>local.dir=/home/innost/workspace/minsheng-flat-dir/&nbsp;&nbsp;</span></span></li><li class=""><span>//注意，根据Android&nbsp;Gradle的规范，只有下面两个属性是必须的，其余都是我自己加的&nbsp;&nbsp;</span></li><li class="alt"><span>sdk.dir=/home/innost/workspace/android-aosp-sdk/&nbsp;&nbsp;</span></li><li class=""><span>ndk.dir=/home/innost/workspace/android-aosp-ndk/&nbsp;&nbsp;</span></li><li class="alt"><span>debug.keystore=/home/innost/workspace/tools/mykeystore.jks&nbsp;&nbsp;</span></li><li class=""><span>sdk.api=android-19&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="plain" style="display: none;">local.dir=/home/innost/workspace/minsheng-flat-dir/
//注意，根据Android Gradle的规范，只有下面两个属性是必须的，其余都是我自己加的
sdk.dir=/home/innost/workspace/android-aosp-sdk/
ndk.dir=/home/innost/workspace/android-aosp-ndk/
debug.keystore=/home/innost/workspace/tools/mykeystore.jks
sdk.api=android-19</pre><br><br><p></p><p>再次强调，<em>sdk.dir</em>和<em>ndk.dir</em>是Android Gradle必须要指定的，其他都是我自己加的属性。当然。不编译ndk，就不需要<em>ndk.dir</em>属性了。</p><h5><a name="t46"></a>3.&nbsp; posdevicebuild.gradle</h5><p>作为multi-project根目录，一般情况下，它的build.gradle是做一些全局配置。来看我的build.gradle</p><p>[posdevicebuild.gradle]</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 35321px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_41" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_41" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=41&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="comment">//下面这个subprojects{}就是一个Script&nbsp;Block</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>subprojects&nbsp;{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;println<span class="string">"Configure&nbsp;for&nbsp;$project.name"</span><span>&nbsp;</span><span class="comment">//遍历子Project，project变量对应每个子Project</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;buildscript&nbsp;{&nbsp;&nbsp;<span class="comment">//这也是一个SB</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;repositories&nbsp;{<span class="comment">//repositories是一个SB</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">///jcenter是一个函数，表示编译过程中依赖的库，所需的插件可以在jcenter仓库中</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//下载。</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jcenter()&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;dependencies&nbsp;{&nbsp;<span class="comment">//SB</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//dependencies表示我们编译的时候，依赖android开发的gradle插件。插件对应的</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//class&nbsp;path是com.android.tools.build。版本是1.2.3</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;classpath<span class="string">'com.android.tools.build:gradle:1.2.3'</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;<span class="comment">//为每个子Project加载utils.gradle&nbsp;。当然，这句话可以放到buildscript花括号之后</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;applyfrom:&nbsp;rootProject.getRootDir().getAbsolutePath()&nbsp;+&nbsp;<span class="string">"/utils.gradle"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;}<span class="comment">//buildscript结束</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">//下面这个subprojects{}就是一个Script Block
subprojects {
  println"Configure for $project.name" //遍历子Project，project变量对应每个子Project
  buildscript {  //这也是一个SB
    repositories {//repositories是一个SB
       ///jcenter是一个函数，表示编译过程中依赖的库，所需的插件可以在jcenter仓库中
       //下载。
       jcenter()
    }
    dependencies { //SB
        //dependencies表示我们编译的时候，依赖android开发的gradle插件。插件对应的
       //class path是com.android.tools.build。版本是1.2.3
        classpath'com.android.tools.build:gradle:1.2.3'
    }
   //为每个子Project加载utils.gradle 。当然，这句话可以放到buildscript花括号之后
   applyfrom: rootProject.getRootDir().getAbsolutePath() + "/utils.gradle"
 }//buildscript结束
}</pre><br><br><p></p><p>感觉解释得好苍白，SB在Gradle的API文档中也是有的。先来看Gradle定义了哪些SB。如图34所示：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194626346" alt=""><br></p><p style="text-align: center;">图34 SB的类型</p></td> </tr></tbody></table></div><br clear="ALL"><p>你看，subprojects、dependencies、repositories都是SB。那么SB到底是什么？它是怎么完成所谓配置的呢？</p><p>仔细研究，你会发现SB后面都需要跟一个花括号，而花括号，恩，我们感觉里边可能一个Closure。由于图34说，这些SB的Description都有“Configure xxx for this project”，所以很可能subprojects是一个函数，然后其参数是一个Closure。是这样的吗？</p><p>Absolutely right。只是这些函数你直接到Project API里不一定能找全。不过要是你好奇心重，不妨到<em>https://docs.gradle.org/current/javadoc/</em>，选择Index这一项，然后ctrl+f，输入图34中任何一个Block，你都会找到对应的函数。比如我替你找了几个API，如图35所示：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194642357" alt=""><br></p><p style="text-align: center;">图35&nbsp;&nbsp; SB对应的函数</p></td> </tr></tbody></table></div><br clear="ALL"><p>特别提示：当你下次看到一个不认识的SB的时候，就去看API吧。</p><p>下面来解释代码中的各个SB：</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>subprojects：它会遍历posdevice中的每个子Project。在它的Closure中，默认参数是子Project对应的Project对象。由于其他SB都在subprojects花括号中，所以相当于对每个Project都配置了一些信息。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>buildscript：它的closure是在一个类型为ScriptHandler的对象上执行的。主意用来所依赖的classpath等信息。通过查看ScriptHandler API可知，在buildscript SB中，你可以调用ScriptHandler提供的repositories(Closure )、dependencies(Closure)函数。这也是为什么repositories和dependencies两个SB为什么要放在buildscript的花括号中的原因。<em>明白了？这就是所谓的行话，得知道规矩。不知道规矩你就乱了。记不住规矩，又不知道查SDK，那么就彻底抓瞎，只能到网上到处找答案了！</em></li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>关于repositories和dependencies，大家直接看API吧。后面碰到了具体代码我们再来介绍</li></ul><p></p><h5><a name="t47"></a>4.&nbsp; CPosDeviceSdkbuild.gradle</h5><p>CPosDeviceSdk是一个Android Library。按Google的想法，Android Library编译出来的应该是一个AAR文件。但是我的项目有些特殊，我需要发布CPosDeviceSdk.jar包给其他人使用。jar在编译过程中会生成，但是它不属于Android Library的标准输出。在这种情况下，我需要在编译完成后，主动copy jar包到我自己设计的产出物目录中。</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 36418px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_42" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_42" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=42&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span class="comment">//Library工程必须加载此插件。注意，加载了Android插件就不要加载Java插件了。因为Android</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="comment">//插件本身就是拓展了Java插件</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>apply&nbsp;plugin:&nbsp;<span class="string">'com.android.library'</span><span>&nbsp;&nbsp;&nbsp;</span></span></li><li class=""><span><span class="comment">//android的编译，增加了一种新类型的ScriptBlock--&gt;android</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>android&nbsp;{&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//你看，我在local.properties中设置的API版本号，就可以一次设置，多个Project使用了</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//借助我特意设计的gradle.ext.api属性</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;compileSdkVersion&nbsp;=gradle.api&nbsp;&nbsp;<span class="comment">//这两个红色的参数必须设置</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buildToolsVersion&nbsp;&nbsp;=&nbsp;<span class="string">"22.0.1"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sourceSets{&nbsp;<span class="comment">//配置源码路径。这个sourceSets是Java插件引入的</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;main{&nbsp;<span class="comment">//main：Android也用了</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;manifest.srcFile&nbsp;<span class="string">'AndroidManifest.xml'</span><span>&nbsp;</span><span class="comment">//这是一个函数，设置manifest.srcFile</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aidl.srcDirs=[<span class="string">'src'</span><span>]&nbsp;</span><span class="comment">//设置aidl文件的目录</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;java.srcDirs=[<span class="string">'src'</span><span>]&nbsp;</span><span class="comment">//设置java文件的目录</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;dependencies&nbsp;{&nbsp;&nbsp;<span class="comment">//配置依赖关系</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//compile表示编译和运行时候需要的jar包，fileTree是一个函数，</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//dir:'libs'，表示搜索目录的名称是libs。include:['*.jar']，表示搜索目录下满足*.jar名字的jar</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//包都作为依赖jar文件</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;compile&nbsp;fileTree(dir:&nbsp;<span class="string">'libs'</span><span>,&nbsp;include:&nbsp;[</span><span class="string">'*.jar'</span><span>])&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>}&nbsp;&nbsp;<span class="comment">//android&nbsp;SB配置完了</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="comment">//clean是一个Task的名字，这个Task好像是Java插件（这里是Android插件）引入的。</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="comment">//dependsOn是一个函数，下面这句话的意思是&nbsp;clean任务依赖cposCleanTask任务。所以</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="comment">//当你gradle&nbsp;clean以执行clean&nbsp;Task的时候，cposCleanTask也会执行</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>clean.dependsOn&nbsp;<span class="string">'cposCleanTask'</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="comment">//创建一个Task，</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>task&nbsp;cposCleanTask()&nbsp;&lt;&lt;{&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;cleanOutput(<span class="keyword">true</span><span>)&nbsp;&nbsp;</span><span class="comment">//cleanOutput是utils.gradle中通过extra属性设置的Closure</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li><li class=""><span><span class="comment">//前面说了，我要把jar包拷贝到指定的目录。对于Android编译，我一般指定gradle&nbsp;assemble</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="comment">//它默认编译debug和release两种输出。所以，下面这个段代码表示：</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="comment">//tasks代表一个Projects中的所有Task，是一个容器。getByName表示找到指定名称的任务。</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="comment">//我这里要找的assemble任务，然后我通过doLast添加了一个Action。这个Action就是copy</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="comment">//产出物到我设置的目标目录中去</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>tasks.getByName(<span class="string">"assemble"</span><span>){&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;it.doLast{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;println&nbsp;<span class="string">"$project.name:&nbsp;After&nbsp;assemble,&nbsp;jar&nbsp;libs&nbsp;are&nbsp;copied&nbsp;tolocal&nbsp;repository"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;copyOutput(<span class="keyword">true</span><span>)&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>}&nbsp;&nbsp;</span></li><li class="alt"><span><span class="comment">/*</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;因为我的项目只提供最终的release编译出来的Jar包给其他人，所以不需要编译debug版的东西</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;当Project创建完所有任务的有向图后，我通过afterEvaluate函数设置一个回调Closure。在这个回调</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;Closure里，我disable了所有Debug的Task</span>&nbsp;</span></li><li class="alt"><span><span class="comment">*/</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>project.afterEvaluate{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;disableDebugBuild()&nbsp;&nbsp;</span></li><li class=""><span>}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">//Library工程必须加载此插件。注意，加载了Android插件就不要加载Java插件了。因为Android
//插件本身就是拓展了Java插件
apply plugin: 'com.android.library' 
//android的编译，增加了一种新类型的ScriptBlock--&gt;android
android {
       //你看，我在local.properties中设置的API版本号，就可以一次设置，多个Project使用了
      //借助我特意设计的gradle.ext.api属性
       compileSdkVersion =gradle.api  //这两个红色的参数必须设置
       buildToolsVersion  = "22.0.1"
       sourceSets{ //配置源码路径。这个sourceSets是Java插件引入的
       main{ //main：Android也用了
           manifest.srcFile 'AndroidManifest.xml' //这是一个函数，设置manifest.srcFile
           aidl.srcDirs=['src'] //设置aidl文件的目录
           java.srcDirs=['src'] //设置java文件的目录
        }
     }
   dependencies {  //配置依赖关系
      //compile表示编译和运行时候需要的jar包，fileTree是一个函数，
     //dir:'libs'，表示搜索目录的名称是libs。include:['*.jar']，表示搜索目录下满足*.jar名字的jar
     //包都作为依赖jar文件
       compile fileTree(dir: 'libs', include: ['*.jar'])
   }
}  //android SB配置完了
//clean是一个Task的名字，这个Task好像是Java插件（这里是Android插件）引入的。
//dependsOn是一个函数，下面这句话的意思是 clean任务依赖cposCleanTask任务。所以
//当你gradle clean以执行clean Task的时候，cposCleanTask也会执行
clean.dependsOn 'cposCleanTask'
//创建一个Task，
task cposCleanTask() &lt;&lt;{
    cleanOutput(true)  //cleanOutput是utils.gradle中通过extra属性设置的Closure
}
//前面说了，我要把jar包拷贝到指定的目录。对于Android编译，我一般指定gradle assemble
//它默认编译debug和release两种输出。所以，下面这个段代码表示：
//tasks代表一个Projects中的所有Task，是一个容器。getByName表示找到指定名称的任务。
//我这里要找的assemble任务，然后我通过doLast添加了一个Action。这个Action就是copy
//产出物到我设置的目标目录中去
tasks.getByName("assemble"){
   it.doLast{
       println "$project.name: After assemble, jar libs are copied tolocal repository"
        copyOutput(true)
     }
}
/*
  因为我的项目只提供最终的release编译出来的Jar包给其他人，所以不需要编译debug版的东西
  当Project创建完所有任务的有向图后，我通过afterEvaluate函数设置一个回调Closure。在这个回调
  Closure里，我disable了所有Debug的Task
*/
project.afterEvaluate{
    disableDebugBuild()
}</pre><br><br><p></p><p>Android自己定义了好多ScriptBlock。Android定义的DSL参考文档在</p><p><em>https://developer.android.com/tools/building/plugin-for-gradle.html</em>下载。注意，它居然没有提供在线文档。</p><p>图36所示为Android的DSL参考信息。</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194701217" alt=""><br></p><p style="text-align: center;">图36&nbsp; Android Gradle DSL参考示意</p></td> </tr></tbody></table></div><br clear="ALL"><p>图37为<em>buildToolsVersion</em>和<em>compileSdkVersion</em>的说明：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194720267" alt=""><br></p><p style="text-align: center;">图37&nbsp; buildToolsVersion和compileSdkVersion的说明</p></td> </tr></tbody></table></div><br clear="ALL"><p>从图37可知，这两个变量是必须要设置的.....</p><h5><a name="t48"></a>5.&nbsp;CPosDeviceServerApk build.gradle</h5><p>再来看一个APK的build，它包含NDK的编译，并且还要签名。根据项目的需求，我们只能签debug版的，而release版的签名得发布unsigned包给领导签名。另外，CPosDeviceServerAPK依赖CPosDeviceSdk。</p><p>虽然我可以先编译CPosDeviceSdk，得到对应的jar包，然后设置CPosDeviceServerApk直接依赖这个jar包就好。但是我更希望CPosDeviceServerApk能直接依赖于CPosDeviceSdk这个工程。这样，整个posdevice可以做到这几个Project的依赖关系是最新的。</p><p>[build.gradle]</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 37869px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_43" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_43" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=43&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>apply&nbsp;plugin:&nbsp;</span><span class="string">'com.android.application'</span><span>&nbsp;&nbsp;</span><span class="comment">//APK编译必须加载这个插件</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>android&nbsp;{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;compileSdkVersion&nbsp;gradle.api&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buildToolsVersion&nbsp;<span class="string">"22.0.1"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sourceSets{&nbsp;&nbsp;<span class="comment">//差不多的设置</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;main{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;manifest.srcFile&nbsp;<span class="string">'AndroidManifest.xml'</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//通过设置jni目录为空，我们可不使用apk插件的jni编译功能。为什么？因为据说</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//APK插件的jni功能好像不是很好使....晕菜</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jni.srcDirs&nbsp;=&nbsp;[]&nbsp;&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jniLibs.srcDir&nbsp;<span class="string">'libs'</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aidl.srcDirs=[<span class="string">'src'</span><span>]&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;java.srcDirs=[<span class="string">'src'</span><span>]&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;res.srcDirs=[<span class="string">'res'</span><span>]&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}<span class="comment">//main结束</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;signingConfigs&nbsp;{&nbsp;<span class="comment">//设置签名信息配置</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debug&nbsp;{&nbsp;&nbsp;<span class="comment">//如果我们在local.properties设置使用特殊的keystore，则使用它</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//下面这些设置，无非是函数调用....请务必阅读API文档</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(project.gradle.debugKeystore&nbsp;!=&nbsp;</span><span class="keyword">null</span><span>){&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;storeFile&nbsp;file(<span class="string">"file://${project.gradle.debugKeystore}"</span><span>)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;storePassword&nbsp;<span class="string">"android"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keyAlias&nbsp;<span class="string">"androiddebugkey"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keyPassword&nbsp;<span class="string">"android"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;}<span class="comment">//signingConfigs结束</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buildTypes&nbsp;{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debug&nbsp;{&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signingConfig&nbsp;signingConfigs.debug&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jniDebuggable&nbsp;<span class="keyword">false</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}<span class="comment">//buildTypes结束</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;dependencies&nbsp;{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//compile：project函数可指定依赖multi-project中的某个子project</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;compile&nbsp;project(<span class="string">':CPosDeviceSdk'</span><span>)&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;compile&nbsp;fileTree(dir:&nbsp;<span class="string">'libs'</span><span>,&nbsp;include:&nbsp;[</span><span class="string">'*.jar'</span><span>])&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;}&nbsp;<span class="comment">//dependices结束</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;repositories{&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;flatDir&nbsp;{<span class="comment">//flatDir：告诉gradle，编译中依赖的jar包存储在dirs指定的目录</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name&nbsp;<span class="string">"minsheng-gradle-local-repository"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dirsgradle.LOCAL_JAR_OUT&nbsp;<span class="comment">//LOCAL_JAR_OUT是我存放编译出来的jar包的位置</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;}<span class="comment">//repositories结束</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>}<span class="comment">//android结束</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="comment">/*</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;创建一个Task，类型是Exec，这表明它会执行一个命令。我这里让他执行ndk的</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;ndk-build命令，用于编译ndk。关于Exec类型的Task，请自行脑补Gradle的API</span>&nbsp;</span></li><li class="alt"><span><span class="comment">*/</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="comment">//注意此处创建task的方法，是直接{}喔，那么它后面的tasks.withType(JavaCompile)</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span><span class="comment">//设置的依赖关系，还有意义吗？Think！如果你能想明白，gradle掌握也就差不多了</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>task&nbsp;buildNative(type:&nbsp;Exec,&nbsp;description:&nbsp;<span class="string">'CompileJNI&nbsp;source&nbsp;via&nbsp;NDK'</span><span>)&nbsp;{&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(project.gradle.ndkDir&nbsp;==&nbsp;</span><span class="keyword">null</span><span>)&nbsp;</span><span class="comment">//看看有没有指定ndk.dir路径</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;println&nbsp;<span class="string">"CANNOT&nbsp;Build&nbsp;NDK"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">else</span><span>{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;commandLine&nbsp;<span class="string">"/${project.gradle.ndkDir}/ndk-build"</span><span>,&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">'-C'</span><span>,&nbsp;file(</span><span class="string">'jni'</span><span>).absolutePath,&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">'-j'</span><span>,&nbsp;Runtime.runtime.availableProcessors(),&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">'all'</span><span>,&nbsp;</span><span class="string">'NDK_DEBUG=0'</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;tasks.withType(JavaCompile)&nbsp;{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;compileTask&nbsp;-&gt;&nbsp;compileTask.dependsOn&nbsp;buildNative&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;......&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;<span class="comment">//对于APK，除了拷贝APK文件到指定目录外，我还特意为它们加上了自动版本命名的功能</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;tasks.getByName(<span class="string">"assemble"</span><span>){&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;it.doLast{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;println&nbsp;<span class="string">"$project.name:&nbsp;After&nbsp;assemble,&nbsp;jar&nbsp;libs&nbsp;are&nbsp;copied&nbsp;tolocal&nbsp;repository"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;project.ext.versionName&nbsp;=&nbsp;android.defaultConfig.versionName&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;println&nbsp;<span class="string">"\t&nbsp;versionName&nbsp;=&nbsp;$versionName"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;copyOutput(<span class="keyword">false</span><span>)&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">apply plugin: 'com.android.application'  //APK编译必须加载这个插件
android {
      compileSdkVersion gradle.api
      buildToolsVersion "22.0.1"
      sourceSets{  //差不多的设置
       main{
           manifest.srcFile 'AndroidManifest.xml'
          //通过设置jni目录为空，我们可不使用apk插件的jni编译功能。为什么？因为据说
         //APK插件的jni功能好像不是很好使....晕菜
          jni.srcDirs = [] 
           jniLibs.srcDir 'libs'
            aidl.srcDirs=['src']
           java.srcDirs=['src']
           res.srcDirs=['res']
        }
    }//main结束
   signingConfigs { //设置签名信息配置
       debug {  //如果我们在local.properties设置使用特殊的keystore，则使用它
           //下面这些设置，无非是函数调用....请务必阅读API文档
           if(project.gradle.debugKeystore != null){
              storeFile file("file://${project.gradle.debugKeystore}")
              storePassword "android"
              keyAlias "androiddebugkey"
              keyPassword "android"
           }
        }
   }//signingConfigs结束
     buildTypes {
       debug {
           signingConfig signingConfigs.debug
           jniDebuggable false
        }
    }//buildTypes结束
   dependencies {
        //compile：project函数可指定依赖multi-project中的某个子project
       compile project(':CPosDeviceSdk')
       compile fileTree(dir: 'libs', include: ['*.jar'])
   } //dependices结束
  repositories{
   flatDir {//flatDir：告诉gradle，编译中依赖的jar包存储在dirs指定的目录
           name "minsheng-gradle-local-repository"
            dirsgradle.LOCAL_JAR_OUT //LOCAL_JAR_OUT是我存放编译出来的jar包的位置
   }
  }//repositories结束
}//android结束
/*
   创建一个Task，类型是Exec，这表明它会执行一个命令。我这里让他执行ndk的
   ndk-build命令，用于编译ndk。关于Exec类型的Task，请自行脑补Gradle的API
*/
//注意此处创建task的方法，是直接{}喔，那么它后面的tasks.withType(JavaCompile)
//设置的依赖关系，还有意义吗？Think！如果你能想明白，gradle掌握也就差不多了
task buildNative(type: Exec, description: 'CompileJNI source via NDK') {
       if(project.gradle.ndkDir == null) //看看有没有指定ndk.dir路径
          println "CANNOT Build NDK"
       else{
            commandLine "/${project.gradle.ndkDir}/ndk-build",
               '-C', file('jni').absolutePath,
               '-j', Runtime.runtime.availableProcessors(),
               'all', 'NDK_DEBUG=0'
        }
  }
 tasks.withType(JavaCompile) {
       compileTask -&gt; compileTask.dependsOn buildNative
  }
  ......  
 //对于APK，除了拷贝APK文件到指定目录外，我还特意为它们加上了自动版本命名的功能
 tasks.getByName("assemble"){
       it.doLast{
       println "$project.name: After assemble, jar libs are copied tolocal repository"
       project.ext.versionName = android.defaultConfig.versionName
       println "\t versionName = $versionName"
       copyOutput(false)
     }
}</pre><br><br><p></p><p>&nbsp;</p><h5><a name="t49"></a>6.&nbsp; 结果展示</h5><p>在posdevice下执行gradle assemble命令，最终的输出文件都会拷贝到我指定的目录，结果如图38所示：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905194741289" alt=""><br></p><p style="text-align: center;">图38&nbsp; posdevice执行结果</p></td> </tr></tbody></table></div><br clear="ALL"><p>图38所示为posdevice<em> gradle assemble</em>的执行结果：</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>library包都编译release版的，copy到xxx/javaLib目录下</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>apk编译debug和release-unsigned版的，copy到apps目录下</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>所有产出物都自动从AndroidManifest.xml中提取versionName。</li></ul><p></p><h4><a name="t50"></a>4.4.4&nbsp; 实例2</h4><p>下面这个实例也是来自一个实际的APP。这个APP对应的是一个单独的Project。但是根据我前面的建议，我会把它改造成支持Multi-ProjectsBuild的样子。即在工程目录下放一个settings.build。</p><p>另外，这个app有一个特点。它有三个版本，分别是debug、release和demo。这三个版本对应的代码都完全一样，但是在运行的时候需要从assets/runtime_config文件中读取参数。参数不同，则运行的时候会跳转到debug、release或者demo的逻辑上。</p><div style="background:#F2F2F2;"><p>注意：我知道assets/runtime_config这种做法不decent，但，这是一个既有项目，我们只能做小范围的适配，而不是伤筋动骨改用更好的方法。另外，从未来的需求来看，暂时也没有大改的必要。</p></div><p>引入gradle后，我们该如何处理呢？</p><p>解决方法是：在编译build、release和demo版本前，在build.gradle中自动设置runtime_config的内容。代码如下所示：</p><p>[build.gradle]</p><p></p><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 444px; top: 39884px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_44" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_44" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=44&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>apply&nbsp;plugin:&nbsp;</span><span class="string">'com.android.application'</span><span>&nbsp;&nbsp;</span><span class="comment">//加载APP插件</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="comment">//加载utils.gradle</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>apply&nbsp;from:rootProject.getRootDir().getAbsolutePath()&nbsp;+&nbsp;<span class="string">"/utils.gradle"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span><span class="comment">//buildscript设置android&nbsp;app插件的位置</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>buildscript&nbsp;{&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;repositories&nbsp;{&nbsp;jcenter()&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;dependencies&nbsp;{&nbsp;classpath&nbsp;<span class="string">'com.android.tools.build:gradle:1.2.3'</span><span>&nbsp;}&nbsp;&nbsp;</span></span></li><li class=""><span>}&nbsp;&nbsp;</span></li><li class="alt"><span><span class="comment">//androidScriptBlock</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>android&nbsp;{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;compileSdkVersion&nbsp;gradle.api&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;buildToolsVersion&nbsp;<span class="string">"22.0.1"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;sourceSets{<span class="comment">//源码设置SB</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;main{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;manifest.srcFile&nbsp;<span class="string">'AndroidManifest.xml'</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jni.srcDirs&nbsp;=&nbsp;[]&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jniLibs.srcDir&nbsp;<span class="string">'libs'</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aidl.srcDirs=[<span class="string">'src'</span><span>]&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;java.srcDirs=[<span class="string">'src'</span><span>]&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;res.srcDirs=[<span class="string">'res'</span><span>]&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assets.srcDirs&nbsp;=&nbsp;[<span class="string">'assets'</span><span>]&nbsp;</span><span class="comment">//多了一个assets目录</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;signingConfigs&nbsp;{<span class="comment">//签名设置</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debug&nbsp;{&nbsp;&nbsp;<span class="comment">//debug对应的SB。注意</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>(project.gradle.debugKeystore&nbsp;!=&nbsp;</span><span class="keyword">null</span><span>){&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;storeFile&nbsp;file(<span class="string">"file://${project.gradle.debugKeystore}"</span><span>)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;storePassword&nbsp;<span class="string">"android"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keyAlias&nbsp;<span class="string">"androiddebugkey"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keyPassword&nbsp;<span class="string">"android"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/*</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;最关键的内容来了：&nbsp;buildTypesScriptBlock.</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buildTypes和上面的signingConfigs，当我们在build.gradle中通过{}配置它的时候，</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其背后的所代表的对象是NamedDomainObjectContainer&lt;BuildType&gt;&nbsp;和</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NamedDomainObjectContainer&lt;SigningConfig&gt;</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;注意，NamedDomainObjectContainer&lt;BuildType/或者SigningConfig&gt;是一种容器，</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;容器的元素是BuildType或者SigningConfig。我们在debug{}要填充BuildType或者</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;SigningConfig所包的元素，比如storePassword就是SigningConfig类的成员。而proguardFile等</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;是BuildType的成员。</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;那么，为什么要使用NamedDomainObjectContainer这种数据结构呢？因为往这种容器里</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;添加元素可以采用这样的方法：&nbsp;比如signingConfig为例</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;signingConfig{//这是一个NamedDomainObjectContainer&lt;SigningConfig&gt;</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;test1{//新建一个名为test1的SigningConfig元素，然后添加到容器里</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//在这个花括号中设置SigningConfig的成员变量的值</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;test2{//新建一个名为test2的SigningConfig元素，然后添加到容器里</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//在这个花括号中设置SigningConfig的成员变量的值</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;}</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;在buildTypes中，Android默认为这几个NamedDomainObjectContainer添加了</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;debug和release对应的对象。如果我们再添加别的名字的东西，那么gradleassemble的时候</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;也会编译这个名字的apk出来。比如，我添加一个名为test的buildTypes，那么gradle&nbsp;assemble</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;就会编译一个xxx-test-yy.apk。在此，test就好像debug、release一样。</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;buildTypes{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debug{&nbsp;<span class="comment">//修改debug的signingConfig为signingConfig.debug配置</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signingConfig&nbsp;signingConfigs.debug&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;demo{&nbsp;<span class="comment">//demo版需要混淆</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proguardFile&nbsp;<span class="string">'proguard-project.txt'</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signingConfig&nbsp;signingConfigs.debug&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//release版没有设置，所以默认没有签名，没有混淆</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;......<span class="comment">//其他和posdevice&nbsp;类似的处理。来看如何动态生成runtime_config文件</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;def&nbsp;&nbsp;runtime_config_file&nbsp;=&nbsp;<span class="string">'assets/runtime_config'</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;<span class="comment">/*</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;我们在gradle解析完整个任务之后，找到对应的Task，然后在里边添加一个doFirst&nbsp;Action</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;这样能确保编译开始的时候，我们就把runtime_config文件准备好了。</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;注意，必须在afterEvaluate里边才能做，否则gradle没有建立完任务有向图，你是找不到</span>&nbsp;</span></li><li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;什么preDebugBuild之类的任务的</span>&nbsp;</span></li><li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;project.afterEvaluate{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//找到preDebugBuild任务，然后添加一个Action&nbsp;</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tasks.getByName(<span class="string">"preDebugBuild"</span><span>){&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;it.doFirst{&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;println&nbsp;<span class="string">"generate&nbsp;debug&nbsp;configuration&nbsp;for&nbsp;${project.name}"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;configFile&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;File(runtime_config_file)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;configFile.withOutputStream{os-&gt;&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os&nbsp;&lt;&lt;&nbsp;I&nbsp;am&nbsp;Debug\n'&nbsp;&nbsp;<span class="comment">//往配置文件里写&nbsp;I&nbsp;am&nbsp;Debug</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//找到preReleaseBuild任务</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tasks.getByName(<span class="string">"preReleaseBuild"</span><span>){&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;it.doFirst{&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;println&nbsp;<span class="string">"generate&nbsp;release&nbsp;configuration&nbsp;for&nbsp;${project.name}"</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;configFile&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;File(runtime_config_file)&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;configFile.withOutputStream{os-&gt;&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os&nbsp;&lt;&lt;&nbsp;I&nbsp;am&nbsp;release\n'&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//找到preDemoBuild。这个任务明显是因为我们在buildType里添加了一个demo的元素</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//所以Android&nbsp;APP插件自动为我们生成的</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tasks.getByName(<span class="string">"preDemoBuild"</span><span>){&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;it.doFirst{&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;println&nbsp;<span class="string">"generate&nbsp;offlinedemo&nbsp;configuration&nbsp;for${project.name}"</span><span>&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;configFile&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;File(runtime_config_file)&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;configFile.withOutputStream{os-&gt;&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os&nbsp;&lt;&lt;&nbsp;I&nbsp;am&nbsp;Demo\n'&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;.....<span class="comment">//copyOutput</span><span>&nbsp;&nbsp;</span></span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="java" style="display: none;">apply plugin: 'com.android.application'  //加载APP插件
//加载utils.gradle
apply from:rootProject.getRootDir().getAbsolutePath() + "/utils.gradle"
//buildscript设置android app插件的位置
buildscript {
   repositories { jcenter() }
   dependencies { classpath 'com.android.tools.build:gradle:1.2.3' }
}
//androidScriptBlock
android {
   compileSdkVersion gradle.api
   buildToolsVersion "22.0.1"
   sourceSets{//源码设置SB
        main{
           manifest.srcFile 'AndroidManifest.xml'
           jni.srcDirs = []
           jniLibs.srcDir 'libs'
           aidl.srcDirs=['src']
           java.srcDirs=['src']
           res.srcDirs=['res']
           assets.srcDirs = ['assets'] //多了一个assets目录
        }
    }
   signingConfigs {//签名设置
       debug {  //debug对应的SB。注意
           if(project.gradle.debugKeystore != null){
               storeFile file("file://${project.gradle.debugKeystore}")
               storePassword "android"
               keyAlias "androiddebugkey"
               keyPassword "android"
           }
        }
    }
    /*
     最关键的内容来了： buildTypesScriptBlock.
     buildTypes和上面的signingConfigs，当我们在build.gradle中通过{}配置它的时候，
     其背后的所代表的对象是NamedDomainObjectContainer&lt;BuildType&gt; 和
     NamedDomainObjectContainer&lt;SigningConfig&gt;
     注意，NamedDomainObjectContainer&lt;BuildType/或者SigningConfig&gt;是一种容器，
     容器的元素是BuildType或者SigningConfig。我们在debug{}要填充BuildType或者
    SigningConfig所包的元素，比如storePassword就是SigningConfig类的成员。而proguardFile等
    是BuildType的成员。
    那么，为什么要使用NamedDomainObjectContainer这种数据结构呢？因为往这种容器里
    添加元素可以采用这样的方法： 比如signingConfig为例
    signingConfig{//这是一个NamedDomainObjectContainer&lt;SigningConfig&gt;
       test1{//新建一个名为test1的SigningConfig元素，然后添加到容器里
         //在这个花括号中设置SigningConfig的成员变量的值
       }
      test2{//新建一个名为test2的SigningConfig元素，然后添加到容器里
         //在这个花括号中设置SigningConfig的成员变量的值
      }
    }
    在buildTypes中，Android默认为这几个NamedDomainObjectContainer添加了
    debug和release对应的对象。如果我们再添加别的名字的东西，那么gradleassemble的时候
    也会编译这个名字的apk出来。比如，我添加一个名为test的buildTypes，那么gradle assemble
    就会编译一个xxx-test-yy.apk。在此，test就好像debug、release一样。
   */
   buildTypes{
        debug{ //修改debug的signingConfig为signingConfig.debug配置
           signingConfig signingConfigs.debug
        }
        demo{ //demo版需要混淆
           proguardFile 'proguard-project.txt'
           signingConfig signingConfigs.debug
        }
       //release版没有设置，所以默认没有签名，没有混淆
    }
      ......//其他和posdevice 类似的处理。来看如何动态生成runtime_config文件
   def  runtime_config_file = 'assets/runtime_config'
   /*
   我们在gradle解析完整个任务之后，找到对应的Task，然后在里边添加一个doFirst Action
   这样能确保编译开始的时候，我们就把runtime_config文件准备好了。
   注意，必须在afterEvaluate里边才能做，否则gradle没有建立完任务有向图，你是找不到
   什么preDebugBuild之类的任务的
   */
   project.afterEvaluate{
      //找到preDebugBuild任务，然后添加一个Action 
      tasks.getByName("preDebugBuild"){
           it.doFirst{
               println "generate debug configuration for ${project.name}"
               def configFile = new File(runtime_config_file)
               configFile.withOutputStream{os-&gt;
                   os &lt;&lt; I am Debug\n'  //往配置文件里写 I am Debug
                }
           }
        }
       //找到preReleaseBuild任务
       tasks.getByName("preReleaseBuild"){
           it.doFirst{
               println "generate release configuration for ${project.name}"
               def configFile = new File(runtime_config_file)
               configFile.withOutputStream{os-&gt;
                   os &lt;&lt; I am release\n'
               }
           }
        }
       //找到preDemoBuild。这个任务明显是因为我们在buildType里添加了一个demo的元素
      //所以Android APP插件自动为我们生成的
       tasks.getByName("preDemoBuild"){
           it.doFirst{
               println "generate offlinedemo configuration for${project.name}"
               def configFile = new File(runtime_config_file)
               configFile.withOutputStream{os-&gt;
                   os &lt;&lt; I am Demo\n'
               }
            }
        }
    }
}
 .....//copyOutput</pre><br><br><p></p><p>&nbsp;</p><p>最终的结果如图39所示：</p><div><table cellspacing="0" cellpadding="0" hspace="0" vspace="0" align="center"> <tbody><tr>  <td valign="top" align="left"><p>     </p>  <p style="text-align: center;"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20150905200639926" alt=""><br></p><p style="text-align: center;">图39&nbsp; 实例2的结果</p></td> </tr></tbody></table></div><br clear="ALL"><p>几个问题，为什么我知道有preXXXBuild这样的任务？</p><p><em>答案：gradle tasks --all查看所有任务。然后，多尝试几次，直到成功</em></p><p>&nbsp;</p><h2><a name="t51"></a>五、总结</h2><p>到此，我个人觉得Gradle相关的内容都讲完了。很难相信我仅花了1个小时不到的时间就为实例2添加了gradle编译支持。在一周以前，我还觉得这是个心病。回想学习gradle的一个月时间里，走过不少弯路，求解问题的思路也和最开始不一样：</p><p></p><ul><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>最开始的时候，我一直把gradle当做脚本看。然后到处到网上找怎么配置gradle。可能能编译成功，但是完全不知道为什么。比如NameDomainObjectContainer，为什么有debug、release。能自己加别的吗？不知道怎么加，没有章法，没有参考。出了问题只能google，找到一个解法，试一试，成功就不管。这么搞，心里不踏实。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>另外，对语法不熟悉，尤其是Groovy语法，虽然看了下快速教材，但总感觉一到gradle就看不懂。主要问题还是闭包，比如Groovy那一节写得文件拷贝的例子中的withOutputStream，还有gradle中的withType，都是些啥玩意啊？</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>所以后来下决心先把Groovy学会，主要是把自己暴露在闭包里边。另外，Groovy是一门语言，总得有SDK说明吧。写了几个例子，慢慢体会到Groovy的好处，也熟悉Groovy的语法了。</li><li><span style="color: rgb(0, 176, 80);">l&nbsp;</span>接着开始看Gradle。Gradle有几本书，我看过Gradle in Action。说实话，看得非常痛苦。现在想起来，Gradle其实比较简单，知道它的生命周期，知道它怎么解析脚本，知道它的API，几乎很快就能干活。而Gradle In Action一上来就很细，而且没有从API角度介绍。说个很有趣的事情，书中有个类似下面的例子</li></ul><p></p><p></p><div class="dp-highlighter bg_plain"><div class="bar"><div class="tools"><b>[plain]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 448px; top: 42519px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_45" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_45" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=45&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1"><li class="alt"><span><span>task&nbsp;myTask&nbsp;&lt;&lt;&nbsp;&nbsp;{&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;&nbsp;println&nbsp;'I&nbsp;am&nbsp;myTask'&nbsp;&nbsp;</span></li><li class="alt"><span>}&nbsp;&nbsp;</span></li></ol><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/save_snippets.png"></a></div></div><pre name="code" class="plain" style="display: none;">task myTask &lt;&lt;  {
   println 'I am myTask'
}</pre><br><br><p></p><p>书中说，如果代码没有加&lt;&lt;，则这个任务在脚本<em>initialization</em>（也就是你无论执行什么任务，这个任务都会被执行，<em>I am myTask</em>都会被输出）的时候执行，如果加了<em>&lt;&lt;</em>，则在gradle myTask后才执行。</p><p>尼玛我开始完全不知道为什么，死记硬背。现在你明白了吗？？？？</p><div style="background:#F2F2F2;"><p>这和我们调用task这个函数的方式有关！如果没有&lt;&lt;，则闭包在task函数返回前会执行，而如果加了&lt;&lt;，则变成调用myTask.doLast添加一个Action了，自然它会等到grdle myTask的时候才会执行！</p></div><p>现在想起这个事情我还是很愤怒，API都说很清楚了......而且，如果你把Gradle当做编程框架来看，对于我们这些程序员来说，写这几百行代码，那还算是事嘛？？</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p>   
</div>




<!-- Baidu Button BEGIN -->




<div class="bdsharebuttonbox tracking-ad bdshare-button-style0-16" style="float: right;" data-mod="popu_172" data-bd-bind="1471268660280">
<a href="http://blog.csdn.net/innost/article/details/48228651#" class="bds_more" data-cmd="more" style="background-position:0 0 !important; background-image: url(http://bdimg.share.baidu.com/static/api/img/share/icons_0_16.png?v=d754dcc0.png) !important" target="_blank"></a>
<a href="http://blog.csdn.net/innost/article/details/48228651#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间" style="background-position:0 -52px !important" target="_blank"></a>
<a href="http://blog.csdn.net/innost/article/details/48228651#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博" style="background-position:0 -104px !important" target="_blank"></a>
<a href="http://blog.csdn.net/innost/article/details/48228651#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博" style="background-position:0 -260px !important" target="_blank"></a>
<a href="http://blog.csdn.net/innost/article/details/48228651#" class="bds_renren" data-cmd="renren" title="分享到人人网" style="background-position:0 -208px !important" target="_blank"></a>
<a href="http://blog.csdn.net/innost/article/details/48228651#" class="bds_weixin" data-cmd="weixin" title="分享到微信" style="background-position:0 -1612px !important" target="_blank"></a>
</div>
<script>window._bd_share_config = { "common": { "bdSnsKey": {}, "bdText": "", "bdMini": "1", "bdMiniList": false, "bdPic": "", "bdStyle": "0", "bdSize": "16" }, "share": {} }; with (document) 0[(getElementsByTagName('head')[0] || body).appendChild(createElement('script')).src = 'http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion=' + ~(-new Date() / 36e5)];</script>
<!-- Baidu Button END -->

   <link rel="stylesheet" href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/blog_detail.css">

    
<!--172.16.140.14-->

<!-- Baidu Button BEGIN -->
<script type="text/javascript" id="bdshare_js" data="type=tools&amp;uid=1536434" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/bds_s_v2.js"></script>

<script type="text/javascript">
    document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=" + Math.ceil(new Date()/3600000)
</script>
<!-- Baidu Button END -->

 

        <div id="digg" articleid="48228651">
            <dl id="btnDigg" class="digg digg_disable" onclick="btndigga();">
               
                 <dt>顶</dt>
                <dd>75</dd>
            </dl>
           
              
            <dl id="btnBury" class="digg digg_disable" onclick="btnburya();">
              
                  <dt>踩</dt>
                <dd>1</dd>               
            </dl>
            
        </div>
     <div class="tracking-ad" data-mod="popu_222"><a href="javascript:void(0);" target="_blank">&nbsp;</a>   </div>
    <div class="tracking-ad" data-mod="popu_223"> <a href="javascript:void(0);" target="_blank">&nbsp;</a></div>
    <script type="text/javascript">
                function btndigga() {
                    $(".tracking-ad[data-mod='popu_222'] a").click();
                }
                function btnburya() {
                    $(".tracking-ad[data-mod='popu_223'] a").click();
                }
            </script>

   <ul class="article_next_prev">
                <li class="prev_article"><span onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_shangyipian&#39;]);location.href=&#39;/innost/article/details/47998605&#39;;">上一篇</span><a href="http://blog.csdn.net/innost/article/details/47998605" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_shangyipian&#39;])">专访民生银行：CPOS平台如何从线下布局移动支付</a></li>
                <li class="next_article"><span onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_xiayipian&#39;]);location.href=&#39;/innost/article/details/49387395&#39;;">下一篇</span><a href="http://blog.csdn.net/innost/article/details/49387395" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_xiayipian&#39;])">深入理解Android之AOP</a></li>
    </ul>

    <div style="clear:both; height:10px;"></div>


        <div class="similar_article" style="">
                <h4>我的同类文章</h4>
                <div class="similar_c" style="margin:20px 0px 0px 0px">
                    <div class="similar_c_t">
                                <label class="similar_cur">
                                    <span style="cursor:pointer" onclick="GetCategoryArticles(&#39;767414&#39;,&#39;Innost&#39;,&#39;foot&#39;,&#39;48228651&#39;);">Android开发系列<em>（106）</em></span>
                                </label>
                    </div>
                   
                    <div class="similar_wrap tracking-ad" data-mod="popu_141" style="max-height:195px;">
                        <a href="http://blog.csdn.net/" style="display:none" target="_blank">http://blog.csdn.net</a>
                        <ul class="similar_list fl"><li><em>•</em><a href="http://blog.csdn.net/Innost/article/details/50976754" id="foot_aritcle_50976754undefined4946399920856872" target="_blank" title="30天入门 Android 开发， Google 与你一起圆梦">30天入门 Android 开发， Google 与你一起圆梦</a><span>2016-03-25</span><label><i>阅读</i><b>3980</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/Innost/article/details/50377905" id="foot_aritcle_50377905undefined37723655487026986" target="_blank" title="深入理解Android之Java虚拟机Dalvik">深入理解Android之Java虚拟机Dalvik</a><span>2015-12-22</span><label><i>阅读</i><b>10918</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/Innost/article/details/47998605" id="foot_aritcle_47998605undefined07748412467143395" target="_blank" title="专访民生银行：CPOS平台如何从线下布局移动支付">专访民生银行：CPOS平台如何从线下布局移动支付</a><span>2015-08-26</span><label><i>阅读</i><b>5915</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/Innost/article/details/47660591" id="foot_aritcle_47660591undefined03275395299663919" target="_blank" title="《深入理解Android 卷III》第七章 深入理解SystemUI">《深入理解Android 卷III》第七章 深入理解SystemUI</a><span>2015-08-14</span><label><i>阅读</i><b>9213</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/Innost/article/details/47660387" id="foot_aritcle_47660387undefined23821786270391887" target="_blank" title="《深入理解Android 卷III》第五章 深入理解Android输入系统">《深入理解Android 卷III》第五章 深入理解Android输入系统</a><span>2015-08-14</span><label><i>阅读</i><b>7526</b></label></li> </ul>

                        <ul class="similar_list fr"><li><em>•</em><a href="http://blog.csdn.net/Innost/article/details/50461783" id="foot_aritcle_50461783undefined33339005281403944" target="_blank" title="深入理解Android之Xposed详解">深入理解Android之Xposed详解</a><span>2016-01-05</span><label><i>阅读</i><b>15093</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/Innost/article/details/49387395" id="foot_aritcle_49387395undefined42475788067166853" target="_blank" title="深入理解Android之AOP">深入理解Android之AOP</a><span>2015-10-24</span><label><i>阅读</i><b>18162</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/Innost/article/details/47660645" id="foot_aritcle_47660645undefined05156477244134794" target="_blank" title="《深入理解Android 卷III》第八章深入理解Android壁纸">《深入理解Android 卷III》第八章深入理解Android壁纸</a><span>2015-08-14</span><label><i>阅读</i><b>7970</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/Innost/article/details/47660471" id="foot_aritcle_47660471undefined3493018876779266" target="_blank" title="《深入理解Android 卷III》第六章 深入理解控件（ViewRoot）系统">《深入理解Android 卷III》第六章 深入理解控件（ViewRoot）系统</a><span>2015-08-14</span><label><i>阅读</i><b>7803</b></label></li> <li><em>•</em><a href="http://blog.csdn.net/Innost/article/details/47660193" id="foot_aritcle_47660193undefined5982530980619305" target="_blank" title="《深入理解Android 卷III》第四章 深入理解WindowManagerService">《深入理解Android 卷III》第四章 深入理解WindowManagerService</a><span>2015-08-14</span><label><i>阅读</i><b>9894</b></label></li> </ul>
                    <a href="http://blog.csdn.net/Innost/article/category/767414" class="MoreArticle">更多文章</a></div>
                </div>
            </div>    
    <script type="text/javascript">
        $(function () {
            GetCategoryArticles('767414', 'Innost','foot','48228651');
        });
    </script>
      
</div>
<div id="suggest">

</div>
         <script language="javascript" type="text/javascript">     
             $(function(){
                 $.get("/Innost/svc/GetSuggestContent/48228651",function(data){
                     $("#suggest").html(data);
                 });     
             });             
         </script>  


<style>
.blog-ass-articl dd {
color: #369;
width: 99%; /*修改行*/
float: left;
overflow: hidden;
font: normal normal 12px/23px "SimSun";
height: 23px;
margin: 0;
padding: 0 0 0 10px;
margin-right: 30px;
background: url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;
}
</style>

 <link rel="stylesheet" href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/replace.css">

<div id="relate" data-mod="popu_218" class="tracking-ad">
        <div class="relate_t">
            <h3><span>参考知识库</span></h3>
        </div>
        <div class="relate_c">
        </div>
</div>
 

<dl class="blog-ass-articl" id="res-relatived"> 
    <div class="embody embody_b" id="libkeyparent" style="display:none">
            <span class="embody_t">更多资料请参考：</span>
            <div class="embody_c" id="libkey"></div>
    </div>


     <dt><span>猜你在找</span></dt>    


   


    <div id="adCollege" style="width: 42%;float: left;"> 
        <script src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/job_reco.js" type="text/javascript"></script> 
        <script type="text/javascript">
            csdn.position.showEdu({
                sourceType: "blog",
                searchType: "detail",
                searchKey: "48228651",
                username: "",
                recordcount: "5",
                containerId: "adCollege" //容器DIV的id。 
            });
        </script> 
    <div class="tracking-ad" data-mod="popu_84"><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px; white-space: nowrap;"><a href="http://edu.csdn.net/course/detail/1497" title="Android必备的Java基础知识(二)" strategy="v4:content" target="_blank">Android必备的Java基础知识(二)</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px; white-space: nowrap;"><a href="http://edu.csdn.net/course/detail/1644" title="Android开发精品课程【Java核心知识】" strategy="v4:content" target="_blank">Android开发精品课程【Java核心知识】</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px; white-space: nowrap;"><a href="http://edu.csdn.net/course/detail/545" title="Android入门实战教程" strategy="v4:content" target="_blank">Android入门实战教程</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px; white-space: nowrap;"><a href="http://edu.csdn.net/course/detail/2272" title="javaScript-高级面向对象视频教程" strategy="v4:content" target="_blank">javaScript-高级面向对象视频教程</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px; white-space: nowrap;"><a href="http://edu.csdn.net/course/detail/800" title="理解JavaScript中的闭包" strategy="v4:content" target="_blank">理解JavaScript中的闭包</a></dd></div></div>  

    
     <div id="res" data-mod="popu_36" class="tracking-ad" style="width: 42%; float: left; margin-right: 30px; display: block;"><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="http://blog.csdn.net/Real_Myth/article/details/49314289" title="深入理解Android之Gradle" strategy="SearchAlgorithm" target="_blank">深入理解Android之Gradle</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="http://blog.csdn.net/qeqeqe236/article/details/48441973" title="深入理解Android之Gradle" strategy="SearchAlgorithm" target="_blank">深入理解Android之Gradle</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="http://blog.csdn.net/DJY1992/article/details/49444087" title="深入理解Android之Gradle" strategy="SearchAlgorithm" target="_blank">深入理解Android之Gradle</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="http://blog.csdn.net/cheyiliu/article/details/48954409" title="深入理解Android之Gradle" strategy="SearchAlgorithm" target="_blank">深入理解Android之Gradle</a></dd><dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="http://blog.csdn.net/u010832572/article/details/50344571" title="深入理解Android之Gradle" strategy="SearchAlgorithm" target="_blank">深入理解Android之Gradle</a></dd></div>
   
</dl>


<script type="text/javascript">
    $(function () {
        setTimeout(function () {
            var searchtitletags = '深入理解Android之Gradle' + ',' + $("#tags").html();
            searchService({
                index: 'blog',
                query: searchtitletags,
                from: 5,
                size: 5,
                appendTo: '#res',
                url: 'recommend',
                his: 2,
                client: "blog_cf_enhance",
                tmpl: '<dd style="background:url(http://static.blog.csdn.net/skin/default/images/blog-dot-red3.gif) no-repeat 0 10px;"><a href="#{ url }" title="#{ title }" strategy="#{ strategy }">#{ title }</a></dd>'
            });
        }, 500);
    });    

 </script>  

    <div id="ad_cen">        
                    <script type="text/javascript">
                        /*博客内容页下方Banner-728*90，创建于2014-7-3*/
                        var cpro_id = "u1607657";
                    </script>
                    <script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/c.js"></script><div id="BAIDU_SSP__wrapper_u1607657_0"><iframe id="iframeu1607657_0" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/ocsm(1).html" width="728" height="90" align="center,center" vspace="0" hspace="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" style="border:0; vertical-align:bottom;margin:0;" allowtransparency="true"></iframe></div>
    </div>  

<div class="comment_class">
    <div id="comment_title" class="panel_head">
        <span class="see_comment">查看评论</span><a name="comments"></a></div>
    <div id="comment_list"><dl class="comment_item comment_topic" id="comment_item_6210144"><dt class="comment_head" floor="85">85楼 <span class="user"><a class="username" href="http://blog.csdn.net/eo_yohe" target="_blank">eo_yohe</a> <span class="ptime">昨天 22:35发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6210144" username="eo_yohe"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/eo_yohe" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_eo_yohe.jpg" width="40" height="40"></a></dd><dd class="comment_body">mark</dd></dl><dl class="comment_item comment_topic" id="comment_item_6147961"><dt class="comment_head" floor="84">84楼 <span class="user"><a class="username" href="http://blog.csdn.net/flyfight88" target="_blank">flyfight88</a> <span class="ptime">2016-07-27 10:21发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6147961" username="flyfight88"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/flyfight88" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_flyfight88.jpg" width="40" height="40"></a></dd><dd class="comment_body">太厉害了，看了半天收获很多，另外有个问题想问博主，对于离线的服务器怎么下载classpath 'com.android.tools.build:gradle:2.1.2'这个插件呢？gradle安装包有离线版的，可是编译android项目的时候这个android插件下载不起来啊，在脚本中有没有配置加载离线android插件的方法呢？</dd></dl><dl class="comment_item comment_topic" id="comment_item_6120241"><dt class="comment_head" floor="83">83楼 <span class="user"><a class="username" href="http://blog.csdn.net/nicks9999" target="_blank">nicks9999</a> <span class="ptime">2016-07-07 17:22发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6120241" username="nicks9999"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/nicks9999" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_nicks9999.jpg" width="40" height="40"></a></dd><dd class="comment_body">//注意此处创建task的方法，是直接{}喔，那么它后面的tasks.withType(JavaCompile)  <br>//设置的依赖关系，还有意义吗？Think！如果你能想明白，gradle掌握也就差不多了 <br><br>这里时间ndk-build会先执行，所以可以不用设置后面的依赖了。这样理解对吗？</dd></dl><dl class="comment_item comment_topic" id="comment_item_6119596"><dt class="comment_head" floor="82">82楼 <span class="user"><a class="username" href="http://blog.csdn.net/Amy_foreverlove" target="_blank">北爱歌</a> <span class="ptime">2016-07-07 11:15发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6119596" username="Amy_foreverlove"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Amy_foreverlove" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_amy_foreverlove.jpg" width="40" height="40"></a></dd><dd class="comment_body">终于看完了，收获很多，感谢！</dd></dl><dl class="comment_item comment_topic" id="comment_item_6116360"><dt class="comment_head" floor="81">81楼 <span class="user"><a class="username" href="http://blog.csdn.net/Amy_foreverlove" target="_blank">北爱歌</a> <span class="ptime">2016-07-04 21:26发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6116360" username="Amy_foreverlove"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Amy_foreverlove" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_amy_foreverlove.jpg" width="40" height="40"></a></dd><dd class="comment_body">XML解析那一段里，使用GPathResult时需要<br>import groovy.util.slurpersupport.GPathResult，否则会报错unable to resolve class GPathResult。<br>［Groovy Version: 2.4.6 JVM: 1.7.0_75］</dd></dl><dl class="comment_item comment_topic" id="comment_item_6107961"><dt class="comment_head" floor="80">80楼 <span class="user"><a class="username" href="http://blog.csdn.net/u012787710" target="_blank">骇客之技术</a> <span class="ptime">2016-06-30 15:23发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6107961" username="u012787710"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u012787710" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_u012787710.jpg" width="40" height="40"></a></dd><dd class="comment_body">楼主写的不错,学到不少,大概了解gradle了,感谢,有些话说的有道理,就得查API文档,文档才是第一老师~</dd></dl><dl class="comment_item comment_topic" id="comment_item_6088230"><dt class="comment_head" floor="79">79楼 <span class="user"><a class="username" href="http://blog.csdn.net/smart198805292819" target="_blank">smart198805292819</a> <span class="ptime">2016-06-19 18:52发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6088230" username="smart198805292819"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/smart198805292819" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_smart198805292819.jpg" width="40" height="40"></a></dd><dd class="comment_body">由夜行侠老师打造的，gradle+springboot+maven实战免费视频，地址www.itjoin.org<br>剖析gradle底层实现原理，gradle各个插件编写</dd></dl><dl class="comment_item comment_topic" id="comment_item_6085530"><dt class="comment_head" floor="78">78楼 <span class="user"><a class="username" href="http://blog.csdn.net/yinwei_you" target="_blank">yinwei_you</a> <span class="ptime">2016-06-16 15:31发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6085530" username="yinwei_you"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/yinwei_you" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_yinwei_you.jpg" width="40" height="40"></a></dd><dd class="comment_body">gradle编译的项目，怎么用mm去编译啊？</dd></dl><dl class="comment_item comment_topic" id="comment_item_6084895"><dt class="comment_head" floor="77">77楼 <span class="user"><a class="username" href="http://blog.csdn.net/u010032372" target="_blank">-琥珀川-</a> <span class="ptime">2016-06-15 21:49发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6084895" username="u010032372"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u010032372" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_u010032372.jpg" width="40" height="40"></a></dd><dd class="comment_body">2016-6-15 Mark</dd></dl><dl class="comment_item comment_topic" id="comment_item_6080335"><dt class="comment_head" floor="76">76楼 <span class="user"><a class="username" href="http://blog.csdn.net/yzp9421" target="_blank">yzp9421</a> <span class="ptime">2016-06-12 14:00发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6080335" username="yzp9421"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/yzp9421" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_yzp9421.jpg" width="40" height="40"></a></dd><dd class="comment_body">感谢楼主辛苦讲解，pdf 文档已经无法下载，能放到其它网盘提供下载吗</dd></dl><dl class="comment_item comment_topic" id="comment_item_6078041"><dt class="comment_head" floor="75">75楼 <span class="user"><a class="username" href="http://blog.csdn.net/hackooo" target="_blank">小灰马</a> <span class="ptime">2016-06-08 17:41发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6078041" username="hackooo"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/hackooo" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_hackooo.jpg" width="40" height="40"></a></dd><dd class="comment_body">从头看到尾，看了我3个小时，怒点32个赞，写这篇得花掉你一天时间吧，赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞</dd><dl class="comment_item comment_reply" id="comment_item_6078705"><dt class="comment_head" floor="75">Re: <span class="user"><a class="username" href="http://blog.csdn.net/Innost" target="_blank">阿拉神农</a> <span class="ptime">2016-06-09 18:32发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6078705" username="Innost"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Innost" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_innost.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复小灰马：谢谢兄弟鼓舞。研究+写 一个月吧。word文档我记得有40多页</dd></dl></dl><dl class="comment_item comment_topic" id="comment_item_6078040"><dt class="comment_head" floor="74">74楼 <span class="user"><a class="username" href="http://blog.csdn.net/hackooo" target="_blank">小灰马</a> <span class="ptime">2016-06-08 17:41发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6078040" username="hackooo"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/hackooo" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_hackooo.jpg" width="40" height="40"></a></dd><dd class="comment_body">从头看到尾，看了我3个小时，怒点32个赞，写这篇得花掉你一天时间吧，赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞赞</dd></dl><dl class="comment_item comment_topic" id="comment_item_6077513"><dt class="comment_head" floor="73">73楼 <span class="user"><a class="username" href="http://blog.csdn.net/dfqin" target="_blank">dfqin</a> <span class="ptime">2016-06-08 11:13发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6077513" username="dfqin"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/dfqin" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_dfqin.jpg" width="40" height="40"></a></dd><dd class="comment_body">mark</dd></dl><dl class="comment_item comment_topic" id="comment_item_6044595"><dt class="comment_head" floor="72">72楼 <span class="user"><a class="username" href="http://blog.csdn.net/minjie0128" target="_blank">minjie0128</a> <span class="ptime">2016-05-21 21:54发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6044595" username="minjie0128"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/minjie0128" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_minjie0128.jpg" width="40" height="40"></a></dd><dd class="comment_body">“如果没有&lt;&lt;，则闭包在task函数返回前会执行，而如果加了&lt;&lt;，则变成调用myTask.doLast添加一个Action了，自然它会等到grdle myTask的时候才会执行”<br><br>对这句话不是太理解，你说 “闭包在task函数返回前会执行”，这个过程只是定义任务的过程，没有调用啊  怎么会执行呢。 闭包是别人调用才执行吧，闭包不会自己调用自己吧！！！ 一直不是太懂？？  希望有哪位高手帮我回答一下</dd></dl><dl class="comment_item comment_topic" id="comment_item_6035668"><dt class="comment_head" floor="71">71楼 <span class="user"><a class="username" href="http://blog.csdn.net/lyabc123456" target="_blank">lyabc123456</a> <span class="ptime">2016-05-13 14:53发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6035668" username="lyabc123456"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lyabc123456" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_lyabc123456.jpg" width="40" height="40"></a></dd><dd class="comment_body">repositories 不一定必须在buildscript花括号中，我在android studio里根目录下的build.gradle看到：<br>allprojects {<br>    repositories {<br>        jcenter()<br>    }<br>}</dd></dl><dl class="comment_item comment_topic" id="comment_item_6032924"><dt class="comment_head" floor="70">70楼 <span class="user"><a class="username" href="http://blog.csdn.net/lyabc123456" target="_blank">lyabc123456</a> <span class="ptime">2016-05-11 14:55发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6032924" username="lyabc123456"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lyabc123456" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_lyabc123456.jpg" width="40" height="40"></a></dd><dd class="comment_body">感谢大师分享，这么多内容，看来我需要慢慢学习，楼主有没有QQ加一个方便以后请教问题~</dd></dl><dl class="comment_item comment_topic" id="comment_item_6005075"><dt class="comment_head" floor="69">69楼 <span class="user"><a class="username" href="http://blog.csdn.net/hlglinglong" target="_blank">w4lle</a> <span class="ptime">2016-04-28 17:14发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6005075" username="hlglinglong"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/hlglinglong" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_hlglinglong.jpg" width="40" height="40"></a></dd><dd class="comment_body">感谢分享，从头看到尾，意犹未尽。</dd></dl><dl class="comment_item comment_topic" id="comment_item_6001671"><dt class="comment_head" floor="68">68楼 <span class="user"><a class="username" href="http://blog.csdn.net/ljzyuhenda" target="_blank">ljzyuhenda</a> <span class="ptime">2016-04-27 11:48发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6001671" username="ljzyuhenda"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/ljzyuhenda" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_ljzyuhenda.jpg" width="40" height="40"></a></dd><dd class="comment_body">跟着楼主的博客做了一遍，收获特别特别特别(再*max)的多，非常非常感谢！大赞！！！</dd></dl><dl class="comment_item comment_topic" id="comment_item_5994593"><dt class="comment_head" floor="67">67楼 <span class="user"><a class="username" href="http://blog.csdn.net/hilyb" target="_blank">hilyb</a> <span class="ptime">2016-04-22 17:11发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5994593" username="hilyb"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/hilyb" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_hilyb.jpg" width="40" height="40"></a></dd><dd class="comment_body">谢谢大牛的分享，能否再分享一下 copyOutput函数的实现呢，我这边也有类似的需求</dd></dl><dl class="comment_item comment_topic" id="comment_item_5994571"><dt class="comment_head" floor="66">66楼 <span class="user"><a class="username" href="http://blog.csdn.net/hilyb" target="_blank">hilyb</a> <span class="ptime">2016-04-22 17:03发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5994571" username="hilyb"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/hilyb" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_hilyb.jpg" width="40" height="40"></a></dd><dd class="comment_body">好深入，太牛X了，大牛，谢谢，很棒</dd></dl><dl class="comment_item comment_topic" id="comment_item_5991285"><dt class="comment_head" floor="65">65楼 <span class="user"><a class="username" href="http://blog.csdn.net/wlwh90" target="_blank">无泪无悔90</a> <span class="ptime">2016-04-20 15:37发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5991285" username="wlwh90"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/wlwh90" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_wlwh90.jpg" width="40" height="40"></a></dd><dd class="comment_body">我是在InfoQ上看到楼主的这篇文章的。当时沉默了3秒，以示膜拜。</dd></dl><dl class="comment_item comment_topic" id="comment_item_5972702"><dt class="comment_head" floor="64">64楼 <span class="user"><a class="username" href="http://blog.csdn.net/u014099894" target="_blank">baiiu</a> <span class="ptime">2016-04-06 22:52发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5972702" username="u014099894"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u014099894" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_u014099894.jpg" width="40" height="40"></a></dd><dd class="comment_body">神作。非常感谢</dd></dl><dl class="comment_item comment_topic" id="comment_item_5968778"><dt class="comment_head" floor="63">63楼 <span class="user"><a class="username" href="http://blog.csdn.net/bizh129015" target="_blank">吖明-松山湖</a> <span class="ptime">2016-04-03 15:07发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5968778" username="bizh129015"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/bizh129015" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_bizh129015.jpg" width="40" height="40"></a></dd><dd class="comment_body">犀利啊 无限膜拜</dd></dl><dl class="comment_item comment_topic" id="comment_item_5941126"><dt class="comment_head" floor="62">62楼 <span class="user"><a class="username" href="http://blog.csdn.net/zzz0001" target="_blank">zzz0001</a> <span class="ptime">2016-03-21 17:42发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5941126" username="zzz0001"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/zzz0001" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_zzz0001.jpg" width="40" height="40"></a></dd><dd class="comment_body">非常感谢您深入浅出的讲解，看过之后真是受益良多。祝您一切顺利，步步高升：)</dd></dl><dl class="comment_item comment_topic" id="comment_item_5936534"><dt class="comment_head" floor="61">61楼 <span class="user"><a class="username" href="http://blog.csdn.net/cokepanm" target="_blank">cokepanm</a> <span class="ptime">2016-03-17 17:48发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5936534" username="cokepanm"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/cokepanm" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_cokepanm.jpg" width="40" height="40"></a></dd><dd class="comment_body">讲的还可以，排版简直不能忍，mark一下</dd></dl><dl class="comment_item comment_topic" id="comment_item_5934955"><dt class="comment_head" floor="60">60楼 <span class="user"><a class="username" href="http://blog.csdn.net/kangjianwei101" target="_blank">StrayedKing</a> <span class="ptime">2016-03-16 18:31发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5934955" username="kangjianwei101"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/kangjianwei101" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_kangjianwei101.jpg" width="40" height="40"></a></dd><dd class="comment_body">赞赞赞！</dd></dl><dl class="comment_item comment_topic" id="comment_item_5918356"><dt class="comment_head" floor="59">59楼 <span class="user"><a class="username" href="http://blog.csdn.net/oLanMoZhiLei1234" target="_blank">EndSmile</a> <span class="ptime">2016-03-04 10:10发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5918356" username="oLanMoZhiLei1234"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/oLanMoZhiLei1234" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_olanmozhilei1234.jpg" width="40" height="40"></a></dd><dd class="comment_body">请问下，想要根据不同的Build Variant执行不同的groovy代码从而配置不同的文件，要把groovy代码放到哪？</dd></dl><dl class="comment_item comment_topic" id="comment_item_5885596"><dt class="comment_head" floor="58">58楼 <span class="user"><a class="username" href="http://blog.csdn.net/newbzhen" target="_blank">newbzhen</a> <span class="ptime">2016-02-18 17:57发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5885596" username="newbzhen"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/newbzhen" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_newbzhen.jpg" width="40" height="40"></a></dd><dd class="comment_body">看过很多gradle教材，总感觉没到点子上，看完了还是不理解，只有这篇，由浅入深，好像是跟着作者一起学习，决定买几本书支持一下作者</dd></dl><dl class="comment_item comment_topic" id="comment_item_5885481"><dt class="comment_head" floor="57">57楼 <span class="user"><a class="username" href="http://blog.csdn.net/caryliu" target="_blank">蒙奇奇1988</a> <span class="ptime">2016-02-18 16:52发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5885481" username="caryliu"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/caryliu" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_caryliu.jpg" width="40" height="40"></a></dd><dd class="comment_body">感谢博主，弱弱的问一下博主，请问大法是哪家公司(⊙o⊙)?</dd><dl class="comment_item comment_reply" id="comment_item_5959401"><dt class="comment_head" floor="57">Re: <span class="user"><a class="username" href="http://blog.csdn.net/dengliulin" target="_blank">月出惊弓鸟</a> <span class="ptime">2016-03-30 17:57发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5959401" username="dengliulin"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/dengliulin" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_dengliulin.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复蒙奇奇1988：大宝法国分公司</dd></dl></dl><dl class="comment_item comment_topic" id="comment_item_5881049"><dt class="comment_head" floor="56">56楼 <span class="user"><a class="username" href="http://blog.csdn.net/lywschxd" target="_blank">lyws东东</a> <span class="ptime">2016-02-14 23:12发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5881049" username="lywschxd"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lywschxd" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_lywschxd.jpg" width="40" height="40"></a></dd><dd class="comment_body">学习了</dd></dl><dl class="comment_item comment_topic" id="comment_item_5881048"><dt class="comment_head" floor="55">55楼 <span class="user"><a class="username" href="http://blog.csdn.net/lywschxd" target="_blank">lyws东东</a> <span class="ptime">2016-02-14 23:12发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5881048" username="lywschxd"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lywschxd" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_lywschxd.jpg" width="40" height="40"></a></dd><dd class="comment_body">学习了！</dd></dl><dl class="comment_item comment_topic" id="comment_item_5878377"><dt class="comment_head" floor="54">54楼 <span class="user"><a class="username" href="http://blog.csdn.net/u013541140" target="_blank">孙强Jimmy</a> <span class="ptime">2016-02-05 14:09发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5878377" username="u013541140"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u013541140" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_u013541140.jpg" width="40" height="40"></a></dd><dd class="comment_body">有个小错误：<br>是gradle properties用来查看所有属性信息，更正一下。</dd></dl><dl class="comment_item comment_topic" id="comment_item_5734579"><dt class="comment_head" floor="53">53楼 <span class="user"><a class="username" href="http://blog.csdn.net/hikyson" target="_blank">Android_Ky</a> <span class="ptime">2015-12-22 23:51发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5734579" username="hikyson"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/hikyson" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_hikyson.jpg" width="40" height="40"></a></dd><dd class="comment_body">深夜看这文章真心是豁然开朗，以前其实就看到过这篇文章，不过没有深究。今天深夜没人打扰，看的入神，不过明天还有事，必须强制睡了。。<br>做个标记：4.3  Gradle工作流程<br>最后感谢博主无私分享。</dd></dl><dl class="comment_item comment_topic" id="comment_item_5734550"><dt class="comment_head" floor="52">52楼 <span class="user"><a class="username" href="http://blog.csdn.net/hikyson" target="_blank">Android_Ky</a> <span class="ptime">2015-12-22 23:10发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5734550" username="hikyson"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/hikyson" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_hikyson.jpg" width="40" height="40"></a></dd><dd class="comment_body">闭包，函数，属性，真心分不清楚啊。。分辨了半天</dd></dl><dl class="comment_item comment_topic" id="comment_item_5724603"><dt class="comment_head" floor="51">51楼 <span class="user"><a class="username" href="http://blog.csdn.net/zzxzhyt" target="_blank">Zhouztashin</a> <span class="ptime">2015-12-16 14:44发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5724603" username="zzxzhyt"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/zzxzhyt" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_zzxzhyt.jpg" width="40" height="40"></a></dd><dd class="comment_body">好文，谢谢 学习了~！</dd></dl><dl class="comment_item comment_topic" id="comment_item_5713993"><dt class="comment_head" floor="50">50楼 <span class="user"><a class="username" href="http://blog.csdn.net/yaochangliang159" target="_blank">孤心泣</a> <span class="ptime">2015-12-11 20:59发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5713993" username="yaochangliang159"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/yaochangliang159" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_yaochangliang159.jpg" width="40" height="40"></a></dd><dd class="comment_body">大神，膜拜了。。。</dd></dl><dl class="comment_item comment_topic" id="comment_item_5713207"><dt class="comment_head" floor="49">49楼 <span class="user"><a class="username" href="http://blog.csdn.net/linbiaojj" target="_blank">霜穆</a> <span class="ptime">2015-12-11 15:58发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5713207" username="linbiaojj"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/linbiaojj" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_linbiaojj.jpg" width="40" height="40"></a></dd><dd class="comment_body">终于看到最全面深入的gradle教程，以前总是用的云里雾里的，感谢博主！</dd></dl><dl class="comment_item comment_topic" id="comment_item_5707733"><dt class="comment_head" floor="48">48楼 <span class="user"><a class="username" href="http://blog.csdn.net/zhoaya188" target="_blank">落会叶飞</a> <span class="ptime">2015-12-09 11:54发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5707733" username="zhoaya188"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/zhoaya188" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_zhoaya188.jpg" width="40" height="40"></a></dd><dd class="comment_body">大爱</dd></dl><dl class="comment_item comment_topic" id="comment_item_5694779"><dt class="comment_head" floor="47">47楼 <span class="user"><a class="username" href="http://blog.csdn.net/qq_23069607" target="_blank">有何不可0307</a> <span class="ptime">2015-12-04 11:14发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5694779" username="qq_23069607"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/qq_23069607" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_qq_23069607.jpg" width="40" height="40"></a></dd><dd class="comment_body">很好很强大</dd></dl><dl class="comment_item comment_topic" id="comment_item_5694363"><dt class="comment_head" floor="46">46楼 <span class="user"><a class="username" href="http://blog.csdn.net/Jack_SivenChen" target="_blank">Jack_SivenChen</a> <span class="ptime">2015-12-04 09:14发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5694363" username="Jack_SivenChen"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Jack_SivenChen" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_jack_sivenchen.jpg" width="40" height="40"></a></dd><dd class="comment_body">很好 赞</dd></dl><dl class="comment_item comment_topic" id="comment_item_5680185"><dt class="comment_head" floor="45">45楼 <span class="user"><a class="username" href="http://blog.csdn.net/Visilij" target="_blank">Visilij</a> <span class="ptime">2015-12-02 12:42发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5680185" username="Visilij"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Visilij" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_visilij.jpg" width="40" height="40"></a></dd><dd class="comment_body">赞！</dd></dl><dl class="comment_item comment_topic" id="comment_item_5625863"><dt class="comment_head" floor="44">44楼 <span class="user"><a class="username" href="http://blog.csdn.net/jiayongbing3200" target="_blank">jiayongbing3200</a> <span class="ptime">2015-11-19 19:28发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5625863" username="jiayongbing3200"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/jiayongbing3200" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_jiayongbing3200.jpg" width="40" height="40"></a></dd><dd class="comment_body">大神请教一个问题：编译一个library，但是在lib中引用了其他jar包，暂时记为A.jar;现在编译生成了class.jar,那怎么把A.jar和class.jar合成一个jar呢？</dd></dl><dl class="comment_item comment_topic" id="comment_item_5616965"><dt class="comment_head" floor="43">43楼 <span class="user"><a class="username" href="http://blog.csdn.net/guolei000" target="_blank">guolei000</a> <span class="ptime">2015-11-16 15:52发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5616965" username="guolei000"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/guolei000" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_guolei000.jpg" width="40" height="40"></a></dd><dd class="comment_body">看过受益匪浅，感谢</dd></dl><dl class="comment_item comment_topic" id="comment_item_5612739"><dt class="comment_head" floor="42">42楼 <span class="user"><a class="username" href="http://blog.csdn.net/u014313623" target="_blank">smarts</a> <span class="ptime">2015-11-13 23:57发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5612739" username="u014313623"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u014313623" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_u014313623.jpg" width="40" height="40"></a></dd><dd class="comment_body">不可思议，咋能做到羊羊精通？</dd></dl><dl class="comment_item comment_topic" id="comment_item_5599963"><dt class="comment_head" floor="41">41楼 <span class="user"><a class="username" href="http://blog.csdn.net/omayyouhappy" target="_blank">清澈@Cherry</a> <span class="ptime">2015-11-09 09:46发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5599963" username="omayyouhappy"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/omayyouhappy" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_omayyouhappy.jpg" width="40" height="40"></a></dd><dd class="comment_body">大神，写的真好，支持支持，会好好认真学习的</dd></dl><dl class="comment_item comment_topic" id="comment_item_5587099"><dt class="comment_head" floor="40">40楼 <span class="user"><a class="username" href="http://blog.csdn.net/yuexiaoli321" target="_blank">yuexiaoli321</a> <span class="ptime">2015-11-03 11:42发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5587099" username="yuexiaoli321"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/yuexiaoli321" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_yuexiaoli321.jpg" width="40" height="40"></a></dd><dd class="comment_body"><div class="dp-highlighter bg_java"><div class="bar"><div class="tools"><b>[java]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 489px; top: 47673px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_46" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_46" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=46&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1" class="dp-j"><li class="alt"><span><span>GPathResult&nbsp;response&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;XmlSlurper().parse(</span><span class="keyword">new</span><span>&nbsp;File(</span><span class="string">"test.xml"</span><span>))&nbsp;&nbsp;</span></span></li></ol></div><pre name="code2" class="java" style="display: none;">GPathResult response = new XmlSlurper().parse(new File("test.xml"))
</pre><br>运行不了，Groovy版本2.4.5，报错MultipleCompilationErrorsException：unable to resolve class GPathResult<br>改成<br>def response = new XmlSlurper().parse(new File("test.xml"))<br>可以运行</dd></dl><dl class="comment_item comment_topic" id="comment_item_5586917"><dt class="comment_head" floor="39">39楼 <span class="user"><a class="username" href="http://blog.csdn.net/yuexiaoli321" target="_blank">yuexiaoli321</a> <span class="ptime">2015-11-03 11:01发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5586917" username="yuexiaoli321"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/yuexiaoli321" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_yuexiaoli321.jpg" width="40" height="40"></a></dd><dd class="comment_body">3.5.1的这一段<br><div class="dp-highlighter bg_plain"><div class="bar"><div class="tools"><b>[plain]</b> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="ViewSource" title="view plain" onclick="dp.sh.Toolbar.Command(&#39;ViewSource&#39;,this);return false;">view plain</a><span data-mod="popu_168"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="CopyToClipboard" title="copy" onclick="dp.sh.Toolbar.Command(&#39;CopyToClipboard&#39;,this);return false;">copy</a><div style="position: absolute; left: 493px; top: 47920px; width: 18px; height: 18px; z-index: 99;"><embed id="ZeroClipboardMovie_47" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="18" height="18" name="ZeroClipboardMovie_47" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=47&amp;width=18&amp;height=18" wmode="transparent"></div></span><span data-mod="popu_169"> <a href="http://blog.csdn.net/innost/article/details/48228651#" class="PrintSource" title="print" onclick="dp.sh.Toolbar.Command(&#39;PrintSource&#39;,this);return false;">print</a></span><a href="http://blog.csdn.net/innost/article/details/48228651#" class="About" title="?" onclick="dp.sh.Toolbar.Command(&#39;About&#39;,this);return false;">?</a></div></div><ol start="1"><li class="alt"><span><span>targetFile.eachLine{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li><li class=""><span>&nbsp;&nbsp;StringoneLine&nbsp;-&gt;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;printlnoneLine&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li class=""><span>&nbsp;&nbsp;&lt;==是不是令人发指？？！&nbsp;&nbsp;</span></li></ol></div><pre name="code2" class="plain" style="display: none;">targetFile.eachLine{   
  StringoneLine -&gt;  
   printlnoneLine      
  &lt;==是不是令人发指？？！
</pre><br>少了一个大括号<br>这一句代码少了空格String oneLine -&gt;println oneLine<br>或者直接line -&gt; println line 也行</dd><dl class="comment_item comment_reply" id="comment_item_5587011"><dt class="comment_head" floor="39">Re: <span class="user"><a class="username" href="http://blog.csdn.net/Innost" target="_blank">阿拉神农</a> <span class="ptime">2015-11-03 11:18发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5587011" username="Innost"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Innost" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_innost.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复yuexiaoli321：多谢兄弟指正</dd></dl></dl><dl class="comment_item comment_topic" id="comment_item_5583467"><dt class="comment_head" floor="38">38楼 <span class="user"><a class="username" href="http://blog.csdn.net/xuxian361" target="_blank">Sundy_Xu</a> <span class="ptime">2015-11-01 21:37发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5583467" username="xuxian361"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/xuxian361" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_xuxian361.jpg" width="40" height="40"></a></dd><dd class="comment_body">赞一个</dd></dl><dl class="comment_item comment_topic" id="comment_item_5575911"><dt class="comment_head" floor="37">37楼 <span class="user"><a class="username" href="http://blog.csdn.net/lostfish123" target="_blank">lostfish123</a> <span class="ptime">2015-10-31 17:07发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5575911" username="lostfish123"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lostfish123" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_lostfish123.jpg" width="40" height="40"></a></dd><dd class="comment_body">我记得你有篇文章写mat的使用的，怎么找不到了。<br>我想请教下，用了android studio 和 gradle后，抓的hprof文件，用mat打开，path  to gc ,为什么不会显示gc路径了呢。path to gc后，左上角会显示：Found 1paths, no more paths left. 你知道为什么不，这个问题困扰我好久了，一直没找到原因</dd><dl class="comment_item comment_reply" id="comment_item_5576001"><dt class="comment_head" floor="37">Re: <span class="user"><a class="username" href="http://blog.csdn.net/Innost" target="_blank">阿拉神农</a> <span class="ptime">2015-10-31 17:19发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5576001" username="Innost"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Innost" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_innost.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复lostfish123：没写过，不知道mat是啥 呵呵</dd><dl class="comment_item comment_reply" id="comment_item_5732368"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/ioniconline" target="_blank">ioniconline</a> <span class="ptime">2015-12-21 13:52发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5732368" username="ioniconline"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/ioniconline" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_ioniconline.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复阿拉神农：内存分析工具</dd></dl></dl></dl><dl class="comment_item comment_topic" id="comment_item_5533261"><dt class="comment_head" floor="36">36楼 <span class="user"><a class="username" href="http://blog.csdn.net/u011656203" target="_blank">慢行的蜗牛</a> <span class="ptime">2015-10-24 21:20发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5533261" username="u011656203"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u011656203" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_u011656203.jpg" width="40" height="40"></a></dd><dd class="comment_body">赞，一直看了多半天</dd></dl><dl class="comment_item comment_topic" id="comment_item_5524911"><dt class="comment_head" floor="35">35楼 <span class="user"><a class="username" href="http://blog.csdn.net/biezhihua" target="_blank">别志华</a> <span class="ptime">2015-10-22 11:14发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5524911" username="biezhihua"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/biezhihua" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_biezhihua.jpg" width="40" height="40"></a></dd><dd class="comment_body">超级攒</dd></dl><dl class="comment_item comment_topic" id="comment_item_5511553"><dt class="comment_head" floor="34">34楼 <span class="user"><a class="username" href="http://blog.csdn.net/u011179993" target="_blank">陈佳志Jazz</a> <span class="ptime">2015-10-16 16:15发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5511553" username="u011179993"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u011179993" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_u011179993.jpg" width="40" height="40"></a></dd><dd class="comment_body">这不是人类能掌握的语言/(ㄒoㄒ)/~~</dd></dl><dl class="comment_item comment_topic" id="comment_item_5506707"><dt class="comment_head" floor="33">33楼 <span class="user"><a class="username" href="http://blog.csdn.net/Jsonhu1203" target="_blank">刷新召唤</a> <span class="ptime">2015-10-14 17:03发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5506707" username="Jsonhu1203"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Jsonhu1203" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_jsonhu1203.jpg" width="40" height="40"></a></dd><dd class="comment_body">虽然看的云里雾里的，但是感觉楼主能够潜心研究这么深入还是比较的佩服！</dd></dl><dl class="comment_item comment_topic" id="comment_item_5506563"><dt class="comment_head" floor="32">32楼 <span class="user"><a class="username" href="http://blog.csdn.net/u012665480" target="_blank">Only永</a> <span class="ptime">2015-10-14 16:27发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5506563" username="u012665480"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u012665480" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_u012665480.jpg" width="40" height="40"></a></dd><dd class="comment_body">学习了。gradle真的需要好好学习一下的</dd></dl><dl class="comment_item comment_topic" id="comment_item_5502735"><dt class="comment_head" floor="31">31楼 <span class="user"><a class="username" href="http://blog.csdn.net/u013438210" target="_blank">如晦</a> <span class="ptime">2015-10-13 11:24发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5502735" username="u013438210"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u013438210" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_u013438210.jpg" width="40" height="40"></a></dd><dd class="comment_body">Gradle Android插件DSL在线文档：http://google.github.io/android-gradle-dsl/<br>现在已经有了。</dd></dl><dl class="comment_item comment_topic" id="comment_item_5499877"><dt class="comment_head" floor="30">30楼 <span class="user"><a class="username" href="http://blog.csdn.net/tsClear" target="_blank">tsClear</a> <span class="ptime">2015-10-12 10:20发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5499877" username="tsClear"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/tsClear" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_tsclear.jpg" width="40" height="40"></a></dd><dd class="comment_body">博主，我想问一下，当我运行curl -s get.gvmtool.net | bash时，产生的是/home/ts/.sdkman这个目录，并不是.gvm目录，这是怎么回事呢</dd></dl><dl class="comment_item comment_topic" id="comment_item_5495683"><dt class="comment_head" floor="29">29楼 <span class="user"><a class="username" href="http://blog.csdn.net/c511039003" target="_blank">c511039003</a> <span class="ptime">2015-10-10 11:33发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5495683" username="c511039003"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/c511039003" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_c511039003.jpg" width="40" height="40"></a></dd><dd class="comment_body">能否精简一下,少一些比喻,毕竟搞这行的智力不会太低.</dd><dl class="comment_item comment_reply" id="comment_item_5500119"><dt class="comment_head" floor="29">Re: <span class="user"><a class="username" href="http://blog.csdn.net/Innost" target="_blank">阿拉神农</a> <span class="ptime">2015-10-12 11:28发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5500119" username="Innost"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Innost" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_innost.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复c511039003：不要以偏概全，你觉得都懂得 略过不看<br>其他兄弟不见得都知道</dd></dl><dl class="comment_item comment_reply" id="comment_item_5496835"><dt class="comment_head" floor="29">Re: <span class="user"><a class="username" href="http://blog.csdn.net/shiyanshiguize" target="_blank">shiyanshiguize</a> <span class="ptime">2015-10-10 16:44发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5496835" username="shiyanshiguize"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/shiyanshiguize" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_shiyanshiguize.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复c511039003：赞一个，你说的对，不过我真的不能把这个文章看完，太枯燥了，我只是刚开始用android studio</dd><dl class="comment_item comment_reply" id="comment_item_5500123"><dt class="comment_head" floor="2">Re: <span class="user"><a class="username" href="http://blog.csdn.net/Innost" target="_blank">阿拉神农</a> <span class="ptime">2015-10-12 11:29发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5500123" username="Innost"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Innost" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_innost.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复shiyanshiguize：你还没碰到困难，如果你去看英文版的gradle的书<br>比这个要枯燥更多<br>慢慢来不着急</dd></dl></dl></dl><dl class="comment_item comment_topic" id="comment_item_5477913"><dt class="comment_head" floor="28">28楼 <span class="user"><a class="username" href="http://blog.csdn.net/lhc2207221755" target="_blank">水田如雅</a> <span class="ptime">2015-09-30 21:50发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5477913" username="lhc2207221755"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/lhc2207221755" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_lhc2207221755.jpg" width="40" height="40"></a></dd><dd class="comment_body">可以构建java web项目么</dd></dl><dl class="comment_item comment_topic" id="comment_item_5457675"><dt class="comment_head" floor="27">27楼 <span class="user"><a class="username" href="http://blog.csdn.net/yewanglei" target="_blank">酒_剑仙</a> <span class="ptime">2015-09-29 11:31发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5457675" username="yewanglei"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/yewanglei" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_yewanglei.jpg" width="40" height="40"></a></dd><dd class="comment_body">niubily</dd></dl><dl class="comment_item comment_topic" id="comment_item_5450687"><dt class="comment_head" floor="26">26楼 <span class="user"><a class="username" href="http://blog.csdn.net/li396858359" target="_blank">hkllzh</a> <span class="ptime">2015-09-28 14:29发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5450687" username="li396858359"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/li396858359" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_li396858359.jpg" width="40" height="40"></a></dd><dd class="comment_body">谢谢博主的文章。以前虽说也能用gradle编译Android项目，但和这里说的一比。不说了，根本没法比。</dd></dl><dl class="comment_item comment_topic" id="comment_item_5425003"><dt class="comment_head" floor="25">25楼 <span class="user"><a class="username" href="http://blog.csdn.net/hcb8278500" target="_blank">hcb8278500</a> <span class="ptime">2015-09-20 15:39发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5425003" username="hcb8278500"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/hcb8278500" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_hcb8278500.jpg" width="40" height="40"></a></dd><dd class="comment_body">又见大神，大伟哥的书必须入了</dd></dl><dl class="comment_item comment_topic" id="comment_item_5423557"><dt class="comment_head" floor="24">24楼 <span class="user"><a class="username" href="http://blog.csdn.net/yuxiatongzhi" target="_blank">与夏同炙</a> <span class="ptime">2015-09-19 16:33发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5423557" username="yuxiatongzhi"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/yuxiatongzhi" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_yuxiatongzhi.jpg" width="40" height="40"></a></dd><dd class="comment_body">厉害</dd></dl><dl class="comment_item comment_topic" id="comment_item_5422573"><dt class="comment_head" floor="23">23楼 <span class="user"><a class="username" href="http://blog.csdn.net/qq_29461259" target="_blank">草丛_搬运工</a> <span class="ptime">2015-09-18 19:12发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5422573" username="qq_29461259"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/qq_29461259" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_qq_29461259.jpg" width="40" height="40"></a></dd><dd class="comment_body">pdf过期了</dd></dl><dl class="comment_item comment_topic" id="comment_item_5415879"><dt class="comment_head" floor="22">22楼 <span class="user"><a class="username" href="http://blog.csdn.net/sinat_16137897" target="_blank">android_jiajia</a> <span class="ptime">2015-09-16 00:22发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5415879" username="sinat_16137897"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/sinat_16137897" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_sinat_16137897.jpg" width="40" height="40"></a></dd><dd class="comment_body">好文章，赞啊！！！！！！！</dd></dl><dl class="comment_item comment_topic" id="comment_item_5415441"><dt class="comment_head" floor="21">21楼 <span class="user"><a class="username" href="http://blog.csdn.net/cheyiliu" target="_blank">cheyiliu</a> <span class="ptime">2015-09-15 20:44发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5415441" username="cheyiliu"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/cheyiliu" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_cheyiliu.jpg" width="40" height="40"></a></dd><dd class="comment_body">如此好文， 不顶对不起楼主的辛苦。</dd></dl><dl class="comment_item comment_topic" id="comment_item_5415261"><dt class="comment_head" floor="20">20楼 <span class="user"><a class="username" href="http://blog.csdn.net/gxl3999" target="_blank">Govien</a> <span class="ptime">2015-09-15 19:01发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5415261" username="gxl3999"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/gxl3999" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_gxl3999.jpg" width="40" height="40"></a></dd><dd class="comment_body">总结的很到位，条理也挺清晰的，由浅入深。阅读此文需要开发人员具备一定的gradle开发经验、groove基础知识</dd></dl><dl class="comment_item comment_topic" id="comment_item_5414557"><dt class="comment_head" floor="19">19楼 <span class="user"><a class="username" href="http://blog.csdn.net/u010826669" target="_blank">舞影凌风</a> <span class="ptime">2015-09-15 15:53发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5414557" username="u010826669"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u010826669" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_u010826669.jpg" width="40" height="40"></a></dd><dd class="comment_body">支持一下</dd></dl><dl class="comment_item comment_topic" id="comment_item_5413599"><dt class="comment_head" floor="18">18楼 <span class="user"><a class="username" href="http://blog.csdn.net/coolstar1204" target="_blank">怀柔老纪</a> <span class="ptime">2015-09-15 10:53发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5413599" username="coolstar1204"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/coolstar1204" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_coolstar1204.jpg" width="40" height="40"></a></dd><dd class="comment_body">讲得很透的一个好文章，不像有些只告诉你要这样，为什么这样没说清楚。</dd></dl><dl class="comment_item comment_topic" id="comment_item_5413189"><dt class="comment_head" floor="17">17楼 <span class="user"><a class="username" href="http://blog.csdn.net/qq_16981033" target="_blank">花落ww</a> <span class="ptime">2015-09-15 09:03发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5413189" username="qq_16981033"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/qq_16981033" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_qq_16981033.jpg" width="40" height="40"></a></dd><dd class="comment_body">很不错的东西,赞一个</dd></dl><dl class="comment_item comment_topic" id="comment_item_5404185"><dt class="comment_head" floor="16">16楼 <span class="user"><a class="username" href="http://blog.csdn.net/sinat_29071599" target="_blank">背包下的影子</a> <span class="ptime">2015-09-10 15:25发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5404185" username="sinat_29071599"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/sinat_29071599" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_sinat_29071599.jpg" width="40" height="40"></a></dd><dd class="comment_body">赞！！！！向你学习</dd></dl><dl class="comment_item comment_topic" id="comment_item_5403439"><dt class="comment_head" floor="15">15楼 <span class="user"><a class="username" href="http://blog.csdn.net/TOYOTA11" target="_blank">阎楠</a> <span class="ptime">2015-09-10 11:37发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5403439" username="TOYOTA11"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/TOYOTA11" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_toyota11.jpg" width="40" height="40"></a></dd><dd class="comment_body">很好的文章，大赞，大赞！</dd></dl><dl class="comment_item comment_topic" id="comment_item_5402623"><dt class="comment_head" floor="14">14楼 <span class="user"><a class="username" href="http://blog.csdn.net/leer_android" target="_blank">leer_android</a> <span class="ptime">2015-09-09 22:34发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5402623" username="leer_android"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/leer_android" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_leer_android.jpg" width="40" height="40"></a></dd><dd class="comment_body">真的不错耶</dd></dl><dl class="comment_item comment_topic" id="comment_item_5401159"><dt class="comment_head" floor="13">13楼 <span class="user"><a class="username" href="http://blog.csdn.net/dongnan2015" target="_blank">dongnan2015</a> <span class="ptime">2015-09-09 13:54发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5401159" username="dongnan2015"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/dongnan2015" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_dongnan2015.jpg" width="40" height="40"></a></dd><dd class="comment_body">学习了,谢谢！</dd><dl class="comment_item comment_reply" id="comment_item_5959390"><dt class="comment_head" floor="13">Re: <span class="user"><a class="username" href="http://blog.csdn.net/dengliulin" target="_blank">月出惊弓鸟</a> <span class="ptime">2016-03-30 17:52发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5959390" username="dengliulin"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/dengliulin" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_dengliulin.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复dongnan2015：看得懂吗</dd></dl></dl><dl class="comment_item comment_topic" id="comment_item_5400921"><dt class="comment_head" floor="12">12楼 <span class="user"><a class="username" href="http://blog.csdn.net/moyameizan" target="_blank">Chrish愿景</a> <span class="ptime">2015-09-09 11:33发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5400921" username="moyameizan"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/moyameizan" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_moyameizan.jpg" width="40" height="40"></a></dd><dd class="comment_body">不愧是大神 另外看完这些也是需要很大的耐性啊</dd><dl class="comment_item comment_reply" id="comment_item_5401011"><dt class="comment_head" floor="12">Re: <span class="user"><a class="username" href="http://blog.csdn.net/Innost" target="_blank">阿拉神农</a> <span class="ptime">2015-09-09 12:25发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5401011" username="Innost"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Innost" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_innost.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复Chrish愿景：下PDF慢慢看。如果不看，那就得每天花时间网上各种搜，结果总得时间还不如静下心来看一篇文章快呵呵</dd></dl></dl><dl class="comment_item comment_topic" id="comment_item_5397991"><dt class="comment_head" floor="11">11楼 <span class="user"><a class="username" href="http://blog.csdn.net/u013438210" target="_blank">如晦</a> <span class="ptime">2015-09-08 11:36发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5397991" username="u013438210"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u013438210" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_u013438210.jpg" width="40" height="40"></a></dd><dd class="comment_body">非常好，看完了，佩服！</dd></dl><dl class="comment_item comment_topic" id="comment_item_5396961"><dt class="comment_head" floor="10">10楼 <span class="user"><a class="username" href="http://blog.csdn.net/qiujuer" target="_blank">Qiujuer</a> <span class="ptime">2015-09-07 23:00发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5396961" username="qiujuer"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/qiujuer" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_qiujuer.jpg" width="40" height="40"></a></dd><dd class="comment_body">写的不错，顶你~~<br>整体来说挺全面的，也是一个学习过程；缺点呢就是有些乱，如果能梳理一下那肯定就更OK了。</dd><dl class="comment_item comment_reply" id="comment_item_5418055"><dt class="comment_head" floor="10">Re: <span class="user"><a class="username" href="http://blog.csdn.net/yuanhang926" target="_blank">yuanhang926</a> <span class="ptime">2015-09-16 20:01发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5418055" username="yuanhang926"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/yuanhang926" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_yuanhang926.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复Qiujuer：你傻逼啊，这是无私奉献，还再这乱评论什么啊?</dd><dl class="comment_item comment_reply" id="comment_item_5421141"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/qiujuer" target="_blank">Qiujuer</a> <span class="ptime">2015-09-18 10:23发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5421141" username="qiujuer"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/qiujuer" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_qiujuer.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复yuanhang926：说实话，我不知道你为什么喷～<br>看了之后就按照自己的感受写一下评论，就成了乱评论了～</dd></dl><dl class="comment_item comment_reply" id="comment_item_5418933"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/Innost" target="_blank">阿拉神农</a> <span class="ptime">2015-09-17 10:18发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5418933" username="Innost"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/Innost" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_innost.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复yuanhang926：不要骂人，都是兄弟</dd></dl></dl></dl><dl class="comment_item comment_topic" id="comment_item_5396057"><dt class="comment_head" floor="9">9楼 <span class="user"><a class="username" href="http://blog.csdn.net/geduo_83" target="_blank">geduo_83</a> <span class="ptime">2015-09-07 17:06发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5396057" username="geduo_83"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/geduo_83" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_geduo_83.jpg" width="40" height="40"></a></dd><dd class="comment_body">感谢博主无私奉献</dd></dl><dl class="comment_item comment_topic" id="comment_item_5395749"><dt class="comment_head" floor="8">8楼 <span class="user"><a class="username" href="http://blog.csdn.net/u011489615" target="_blank">马甲大王</a> <span class="ptime">2015-09-07 16:03发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5395749" username="u011489615"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u011489615" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_u011489615.jpg" width="40" height="40"></a></dd><dd class="comment_body">看完得需要多大 的毅力啊。</dd></dl><dl class="comment_item comment_topic" id="comment_item_5395127"><dt class="comment_head" floor="7">7楼 <span class="user"><a class="username" href="http://blog.csdn.net/briblue" target="_blank">frank909</a> <span class="ptime">2015-09-07 11:48发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5395127" username="briblue"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/briblue" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_briblue.jpg" width="40" height="40"></a></dd><dd class="comment_body">这才是真正的大神。</dd></dl><dl class="comment_item comment_topic" id="comment_item_5394975"><dt class="comment_head" floor="6">6楼 <span class="user"><a class="username" href="http://blog.csdn.net/zheng5229875" target="_blank">p1aywind</a> <span class="ptime">2015-09-07 11:11发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5394975" username="zheng5229875"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/zheng5229875" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_zheng5229875.jpg" width="40" height="40"></a></dd><dd class="comment_body">大法是哪个公司v</dd><dl class="comment_item comment_reply" id="comment_item_5511571"><dt class="comment_head" floor="6">Re: <span class="user"><a class="username" href="http://blog.csdn.net/a250620111" target="_blank">a250620111</a> <span class="ptime">2015-10-16 16:25发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5511571" username="a250620111"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/a250620111" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_a250620111.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复p1aywind：索尼啊   都说索尼大法好</dd></dl></dl><dl class="comment_item comment_topic" id="comment_item_5392869"><dt class="comment_head" floor="5">5楼 <span class="user"><a class="username" href="http://blog.csdn.net/u013819806" target="_blank">阿牛牛牛牛</a> <span class="ptime">2015-09-06 14:06发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5392869" username="u013819806"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u013819806" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_u013819806.jpg" width="40" height="40"></a></dd><dd class="comment_body">学习</dd></dl><dl class="comment_item comment_topic" id="comment_item_5392789"><dt class="comment_head" floor="4">4楼 <span class="user"><a class="username" href="http://blog.csdn.net/appte" target="_blank">东凌爱</a> <span class="ptime">2015-09-06 13:21发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5392789" username="appte"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/appte" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_appte.jpg" width="40" height="40"></a></dd><dd class="comment_body">非常棒的博客，谢谢博主</dd></dl><dl class="comment_item comment_topic" id="comment_item_5392465"><dt class="comment_head" floor="3">3楼 <span class="user"><a class="username" href="http://blog.csdn.net/u010331406" target="_blank">追风917</a> <span class="ptime">2015-09-06 10:33发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5392465" username="u010331406"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/u010331406" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_u010331406.jpg" width="40" height="40"></a></dd><dd class="comment_body">好深入，谢谢，很棒</dd></dl><dl class="comment_item comment_topic" id="comment_item_5391839"><dt class="comment_head" floor="2">2楼 <span class="user"><a class="username" href="http://blog.csdn.net/x359981514" target="_blank">eclipse_xu</a> <span class="ptime">2015-09-05 20:44发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5391839" username="x359981514"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/x359981514" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_x359981514.jpg" width="40" height="40"></a></dd><dd class="comment_body">大赞~~</dd></dl><dl class="comment_item comment_topic" id="comment_item_5391827"><dt class="comment_head" floor="1">1楼 <span class="user"><a class="username" href="http://blog.csdn.net/ws15286832380" target="_blank">noah199001</a> <span class="ptime">2015-09-05 20:36发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="5391827" username="ws15286832380"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/ws15286832380" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_ws15286832380.jpg" width="40" height="40"></a></dd><dd class="comment_body">学习</dd><dl class="comment_item comment_reply" id="comment_item_6088232"><dt class="comment_head" floor="1">Re: <span class="user"><a class="username" href="http://blog.csdn.net/smart198805292819" target="_blank">smart198805292819</a> <span class="ptime">2016-06-19 18:53发表</span>  <a href="http://blog.csdn.net/innost/article/details/48228651#reply" class="cmt_btn reply" title="回复">[回复]</a> <span class="comment_manage" style="display:none;" commentid="6088232" username="smart198805292819"> <a href="http://blog.csdn.net/innost/article/details/48228651#quote" class="cmt_btn quote" title="引用">[引用]</a> <a href="http://blog.csdn.net/innost/article/details/48228651#report" class="cmt_btn report" title="举报">[举报]</a></span></span></dt><dd class="comment_userface"><a href="http://blog.csdn.net/smart198805292819" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/3_smart198805292819.jpg" width="40" height="40"></a></dd><dd class="comment_body">回复noah199001：gradle+springboot+maven实战免费视频，地址 http://www.itjoin.org/course/detail/575771f20cf22db210ccab6b 剖析gradle底层实现原理，gradle各个插件编写</dd></dl></dl><div class="clear"></div></div>
    <div id="comment_bar" style="display: none;">
    </div>
    <div id="comment_form"><div class="guest_link">您还没有登录,请<a href="javascript:void(0);" onclick="javascript:loginbox();">[登录]</a>或<a href="http://passport.csdn.net/account/register?from=http%3A%2F%2Fblog.csdn.net%2Finnost%2Farticle%2Fdetails%2F48228651">[注册]</a></div></div>
    <div class="announce">
        * 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场<a name="reply"></a><a name="quote"></a></div>
</div>

<script type="text/javascript">
    var fileName = '48228651';
    var commentscount = 101;
    var islock = false
</script>
<script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/comment.js"></script>
    <div id="ad_bot">
    </div>
<div id="report_dialog">
</div>

<div id="d-top" style="bottom:60px;">
        <a id="quick-reply" class="btn btn-top q-reply" title="快速回复" style="display:none;">
            <img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/blog-icon-reply.png" alt="快速回复">
        </a>    

    <a id="d-top-a" class="btn btn-top backtop" style="display: none;" title="返回顶部" onclick="_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_huidaodingbu&#39;])">         
         <img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/top.png" alt="TOP">
    </a>
</div>
<script type="text/javascript">
    $(function ()
    {
        $("#ad_frm_0").height("90px");
        
        setTimeout(function(){
            $("#ad_frm_2").height("200px");
        },1000);    
    });
  
</script>
<style type="text/css">
    .tag_list
    {
        background: none repeat scroll 0 0 #FFFFFF;
        border: 1px solid #D7CBC1;
        color: #000000;
        font-size: 12px;
        line-height: 20px;
        list-style: none outside none;
        margin: 10px 2% 0 1%;
        padding: 1px;
    }
    .tag_list h5
    {
        background: none repeat scroll 0 0 #E0DBD3;
        color: #47381C;
        font-size: 12px;
        height: 24px;
        line-height: 24px;
        padding: 0 5px;
        margin: 0;
    }
    .tag_list h5 a
    {
        color: #47381C;
    }
    .classify
    {
        margin: 10px 0;
        padding: 4px 12px 8px;
    }
    .classify a
    {
        margin-right: 20px;
        white-space: nowrap;
    }
</style>


<div class="tag_list" style="">

    <h5>
        <a href="http://www.csdn.net/tag/" target="_blank">核心技术类目</a></h5>
    <div class="classify">
<a title="全部主题" href="http://www.csdn.net/tag" target="_blank" onclick="LogClickCount(this,336);">全部主题</a>
<a title="Hadoop" href="http://g.csdn.net/5272865" target="_blank" onclick="LogClickCount(this,336);">Hadoop</a>
<a title="AWS" href="http://g.csdn.net/5272866" target="_blank" onclick="LogClickCount(this,336);">AWS</a>
<a title="移动游戏" href="http://g.csdn.net/5272870" target="_blank" onclick="LogClickCount(this,336);">移动游戏</a>
<a title="Java" href="http://g.csdn.net/5272871" target="_blank" onclick="LogClickCount(this,336);">Java</a>
<a title="Android" href="http://g.csdn.net/5272872" target="_blank" onclick="LogClickCount(this,336);">Android</a>
<a title="iOS" href="http://g.csdn.net/5272873" target="_blank" onclick="LogClickCount(this,336);">iOS</a>
<a title="Swift" href="http://g.csdn.net/5272868" target="_blank" onclick="LogClickCount(this,336);">Swift</a>
<a title="智能硬件" href="http://g.csdn.net/5272869" target="_blank" onclick="LogClickCount(this,336);">智能硬件</a>
<a title="Docker" href="http://g.csdn.net/5272867" target="_blank" onclick="LogClickCount(this,336);">Docker</a>
<a title="OpenStack" href="http://g.csdn.net/5272925" target="_blank" onclick="LogClickCount(this,336);">OpenStack</a>
<a title="VPN" href="http://www.csdn.net/tag/vpn" target="_blank" onclick="LogClickCount(this,336);">VPN</a>
<a title="Spark" href="http://g.csdn.net/5272924" target="_blank" onclick="LogClickCount(this,336);">Spark</a>
<a title="ERP" href="http://www.csdn.net/tag/erp" target="_blank" onclick="LogClickCount(this,336);">ERP</a>
<a title="IE10" href="http://www.csdn.net/tag/ie10" target="_blank" onclick="LogClickCount(this,336);">IE10</a>
<a title="Eclipse" href="http://www.csdn.net/tag/eclipse" target="_blank" onclick="LogClickCount(this,336);">Eclipse</a>
<a title="CRM" href="http://www.csdn.net/tag/crm" target="_blank" onclick="LogClickCount(this,336);">CRM</a>
<a title="JavaScript" href="http://www.csdn.net/tag/javascript" target="_blank" onclick="LogClickCount(this,336);">JavaScript</a>
<a title="数据库" href="http://www.csdn.net/tag/%E6%95%B0%E6%8D%AE%E5%BA%93" target="_blank" onclick="LogClickCount(this,336);">数据库</a>
<a title="Ubuntu" href="http://www.csdn.net/tag/ubuntu" target="_blank" onclick="LogClickCount(this,336);">Ubuntu</a>
<a title="NFC" href="http://www.csdn.net/tag/nfc" target="_blank" onclick="LogClickCount(this,336);">NFC</a>
<a title="WAP" href="http://www.csdn.net/tag/wap" target="_blank" onclick="LogClickCount(this,336);">WAP</a>
<a title="jQuery" href="http://www.csdn.net/tag/jquery" target="_blank" onclick="LogClickCount(this,336);">jQuery</a>
<a title="BI" href="http://www.csdn.net/tag/bi" target="_blank" onclick="LogClickCount(this,336);">BI</a>
<a title="HTML5" href="http://www.csdn.net/tag/html5" target="_blank" onclick="LogClickCount(this,336);">HTML5</a>
<a title="Spring" href="http://www.csdn.net/tag/spring" target="_blank" onclick="LogClickCount(this,336);">Spring</a>
<a title="Apache" href="http://www.csdn.net/tag/apache" target="_blank" onclick="LogClickCount(this,336);">Apache</a>
<a title=".NET" href="http://www.csdn.net/tag/.net" target="_blank" onclick="LogClickCount(this,336);">.NET</a>
<a title="API" href="http://www.csdn.net/tag/api" target="_blank" onclick="LogClickCount(this,336);">API</a>
<a title="HTML" href="http://www.csdn.net/tag/html" target="_blank" onclick="LogClickCount(this,336);">HTML</a>
<a title="SDK" href="http://www.csdn.net/tag/sdk" target="_blank" onclick="LogClickCount(this,336);">SDK</a>
<a title="IIS" href="http://www.csdn.net/tag/iis" target="_blank" onclick="LogClickCount(this,336);">IIS</a>
<a title="Fedora" href="http://www.csdn.net/tag/fedora" target="_blank" onclick="LogClickCount(this,336);">Fedora</a>
<a title="XML" href="http://www.csdn.net/tag/xml" target="_blank" onclick="LogClickCount(this,336);">XML</a>
<a title="LBS" href="http://www.csdn.net/tag/lbs" target="_blank" onclick="LogClickCount(this,336);">LBS</a>
<a title="Unity" href="http://www.csdn.net/tag/unity" target="_blank" onclick="LogClickCount(this,336);">Unity</a>
<a title="Splashtop" href="http://www.csdn.net/tag/splashtop" target="_blank" onclick="LogClickCount(this,336);">Splashtop</a>
<a title="UML" href="http://www.csdn.net/tag/uml" target="_blank" onclick="LogClickCount(this,336);">UML</a>
<a title="components" href="http://www.csdn.net/tag/components" target="_blank" onclick="LogClickCount(this,336);">components</a>
<a title="Windows Mobile" href="http://www.csdn.net/tag/windowsmobile" target="_blank" onclick="LogClickCount(this,336);">Windows Mobile</a>
<a title="Rails" href="http://www.csdn.net/tag/rails" target="_blank" onclick="LogClickCount(this,336);">Rails</a>
<a title="QEMU" href="http://www.csdn.net/tag/qemu" target="_blank" onclick="LogClickCount(this,336);">QEMU</a>
<a title="KDE" href="http://www.csdn.net/tag/kde" target="_blank" onclick="LogClickCount(this,336);">KDE</a>
<a title="Cassandra" href="http://www.csdn.net/tag/cassandra" target="_blank" onclick="LogClickCount(this,336);">Cassandra</a>
<a title="CloudStack" href="http://www.csdn.net/tag/cloudstack" target="_blank" onclick="LogClickCount(this,336);">CloudStack</a>
<a title="FTC" href="http://www.csdn.net/tag/ftc" target="_blank" onclick="LogClickCount(this,336);">FTC</a>
<a title="coremail" href="http://www.csdn.net/tag/coremail" target="_blank" onclick="LogClickCount(this,336);">coremail</a>
<a title="OPhone " href="http://www.csdn.net/tag/ophone" target="_blank" onclick="LogClickCount(this,336);">OPhone </a>
<a title="CouchBase" href="http://www.csdn.net/tag/couchbase" target="_blank" onclick="LogClickCount(this,336);">CouchBase</a>
<a title="云计算" href="http://www.csdn.net/tag/%E4%BA%91%E8%AE%A1%E7%AE%97" target="_blank" onclick="LogClickCount(this,336);">云计算</a>
<a title="iOS6" href="http://www.csdn.net/tag/iOS6" target="_blank" onclick="LogClickCount(this,336);">iOS6</a>
<a title="Rackspace " href="http://www.csdn.net/tag/rackspace" target="_blank" onclick="LogClickCount(this,336);">Rackspace </a>
<a title="Web App" href="http://www.csdn.net/tag/webapp" target="_blank" onclick="LogClickCount(this,336);">Web App</a>
<a title="SpringSide" href="http://www.csdn.net/tag/springside" target="_blank" onclick="LogClickCount(this,336);">SpringSide</a>
<a title="Maemo" href="http://www.csdn.net/tag/maemo" target="_blank" onclick="LogClickCount(this,336);">Maemo</a>
<a title="Compuware" href="http://www.csdn.net/tag/compuware" target="_blank" onclick="LogClickCount(this,336);">Compuware</a>
<a title="大数据" href="http://www.csdn.net/tag/%E5%A4%A7%E6%95%B0%E6%8D%AE" target="_blank" onclick="LogClickCount(this,336);">大数据</a>
<a title="aptech" href="http://www.csdn.net/tag/aptech" target="_blank" onclick="LogClickCount(this,336);">aptech</a>
<a title="Perl" href="http://www.csdn.net/tag/perl" target="_blank" onclick="LogClickCount(this,336);">Perl</a>
<a title="Tornado" href="http://www.csdn.net/tag/tornado" target="_blank" onclick="LogClickCount(this,336);">Tornado</a>
<a title="Ruby" href="http://www.csdn.net/tag/ruby" target="_blank" onclick="LogClickCount(this,336);">Ruby</a>
<a title="Hibernate" href="http://www.csdn.net/hibernate" target="_blank" onclick="LogClickCount(this,336);">Hibernate</a>
<a title="ThinkPHP" href="http://www.csdn.net/tag/thinkphp" target="_blank" onclick="LogClickCount(this,336);">ThinkPHP</a>
<a title="HBase" href="http://www.csdn.net/tag/hbase" target="_blank" onclick="LogClickCount(this,336);">HBase</a>
<a title="Pure" href="http://www.csdn.net/tag/pure" target="_blank" onclick="LogClickCount(this,336);">Pure</a>
<a title="Solr" href="http://www.csdn.net/tag/solr" target="_blank" onclick="LogClickCount(this,336);">Solr</a>
<a title="Angular" href="http://www.csdn.net/tag/angular" target="_blank" onclick="LogClickCount(this,336);">Angular</a>
<a title="Cloud Foundry" href="http://www.csdn.net/tag/cloudfoundry" target="_blank" onclick="LogClickCount(this,336);">Cloud Foundry</a>
<a title="Redis" href="http://www.csdn.net/tag/redis" target="_blank" onclick="LogClickCount(this,336);">Redis</a>
<a title="Scala" href="http://www.csdn.net/tag/scala" target="_blank" onclick="LogClickCount(this,336);">Scala</a>
<a title="Django" href="http://www.csdn.net/tag/django" target="_blank" onclick="LogClickCount(this,336);">Django</a>
<a title="Bootstrap" href="http://www.csdn.net/tag/bootstrap" target="_blank" onclick="LogClickCount(this,336);">Bootstrap</a>
    </div>

</div>
  <script language="javascript" type="text/javascript">     
      $(function(){
              setTimeout(function(){
                  $.get("/Innost/svc/GetTagContent",function(data){
                      $(".tag_list").html(data).show();
                  });     
              });
          },500);                       
 </script> 


<div id="pop_win" style="display:none ;position: absolute; z-index: 10000; border: 1px solid rgb(220, 220, 220); top: 222.5px; left: 630px; opacity: 1; background: none 0px 0px repeat scroll rgb(255, 255, 255);">
    
</div>
<div id="popup_mask"></div>
<style>
    #popup_mask
    {
        position: absolute;
        width: 100%;
        height: 100%;
        background: #000;
        z-index: 9999;
        left: 0px;
        top: 0px;
        opacity: 0.3;
        filter: alpha(opacity=30);
        display: none;
    }

</style>




<script type="text/javascript">
    $(function(){
        setTimeout(function(){
            $(".comment_body:contains('回复')").each(function(index,item){
                var u=$(this).text().split('：')[0].toString().replace("回复","")
                var thisComment=$(this);
                if(u)
                {
                    $.getJSON("https://passport.csdn.net/get/nick?callback=?", {users: u}, function(a) {
                        if(a!=null&&a.data!=null&&a.data.length>0)
                        {
                            nick=a.data[0].n; 
                            if(u!=nick)
                            {
                                thisComment.text(thisComment.text().replace(u,nick));  
                            }
                        }       
                    });  
                }
            });         

        },200);  

        setTimeout(function(){
            $(".math").each(function(index,value){$(this).find("span").last().css("color","#fff"); })
        },5000);

        setTimeout(function(){
            $(".math").each(function(index,value){$(this).find("span").last().css("color","#fff"); })
        },10000);

        setTimeout(function(){
            $(".math").each(function(index,value){$(this).find("span").last().css("color","#fff"); })
        },15000);
        
        setTimeout(function(){
            $("a img[src='http://js.tongji.linezing.com/stats.gif']").parent().css({"position":"absolute","left":"50%"});
        },300);
    });

    function loginbox(){
        var $logpop=$("#pop_win");
        $logpop.html('<iframe src="https://passport.csdn.net/account/loginbox?service=http://static.blog.csdn.net/callback.htm" frameborder="0" height="600" width="400" scrolling="no"></iframe>');

        $('#popup_mask').css({
            opacity: 0.5,
            width: $( document ).width() + 'px',
            height:  $( document ).height() + 'px'
        });
        $('#popup_mask').css("display","block");
 
        $logpop.css( {
            top: ($( window ).height() - $logpop.height())/ 2  + $( window 
       ).scrollTop() + 'px',
            left:($( window ).width() - $logpop.width())/ 2
        } );
 
        setTimeout( function () {
            $logpop.show();
            $logpop.css( {
                opacity: 1
            } );
        }, 200 );
 
        $('#popup_mask').unbind("click");
        $('#popup_mask').bind("click", function(){
            $('#popup_mask').hide();
            var $clopop = $("#pop_win");
            $("#common_ask_div_sc").css("display","none");
            $clopop.css( {
                opacity: 0
            } );
            setTimeout( function () {
                $clopop.hide();
            }, 350 );
            return false;
        });
    }   

</script>
 <script language="javascript" type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/async_new.js"></script>      


                        <div class="clear">
                        </div>
                    </div>                   
                
            </div>
                   
           <div id="side">
    <div class="side">
<div id="panel_Profile" class="panel">
<ul class="panel_head"><span>个人资料</span></ul>
<ul class="panel_body profile">
<div id="blog_userface">
    <a href="http://my.csdn.net/Innost" target="_blank">
    <img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/1_innost.jpg" title="访问我的空间" style="max-width:90%">
    </a>
    <br>
    <span><a href="http://my.csdn.net/Innost" class="user_name" target="_blank">阿拉神农</a></span>
</div>
<div class="interact">

    <a href="javascript:void(0);" class="attent" id="span_add_follow" title="[加关注]"></a>

 <a href="javascript:void(0);" class="letter" title="[发私信]" onclick="window.open(&#39;http://msg.csdn.net/letters/model?receiver=Innost&#39;,&#39;_blank&#39;,&#39;height=350,width=700&#39;);_gaq.push([&#39;_trackEvent&#39;,&#39;function&#39;, &#39;onclick&#39;, &#39;blog_articles_sixin&#39;])"></a>  
</div>
<div id="blog_medal">
                       <div class="ico_expert" onclick="javascript:location=&#39;http://blog.csdn.net/experts/rule.html&#39;" title="CSDN认证专家" style="cursor:pointer;width:60px;height:60px;background:url(&#39;http://c.csdnimg.cn/jifen/images/xunzhang/xunzhang/bokezhuanjiamiddle.png&#39;) no-repeat"></div>
                <div id="bms_box">
                                            <a target="_blank">
                                                    <img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/zhuanlandaren.png" onmouseover="m_over_m(this,2)" onmouseout="m_out_m()" alt="2">
                                            </a>
               </div>
</div>
<ul id="blog_rank">
    <li>访问：<span>1846981次</span></li>
    <li>积分：<span>16825</span> </li>    
    <li>等级： <span style="position:relative;display:inline-block;z-index:1">
            <img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/blog7.png" alt="" style="vertical-align: middle;" id="leveImg">
            <div id="smallTittle" style=" position: absolute;  left: -24px;  top: 25px;  text-align: center;  width: 101px;  height: 32px;  background-color: #fff;  line-height: 32px;  border: 2px #DDDDDD solid;  box-shadow: 0px 2px 2px rgba (0,0,0,0.1);  display: none;   z-index: 999;">
            <div style="left: 42%;  top: -8px;  position: absolute;  width: 0;  height: 0;  border-left: 10px solid transparent;  border-right: 10px solid transparent;  border-bottom: 8px solid #EAEAEA;"></div>
            积分：16825 </div>
        </span>  </li>
    <li>排名：<span>第370名</span></li>
</ul>
<ul id="blog_statistics">
    <li>原创：<span>151篇</span></li>
    <li>转载：<span>4篇</span></li>
    <li>译文：<span>0篇</span></li>
    <li>评论：<span>2098条</span></li>
</ul>
</ul>
</div>




<div id="custom_column_9063568" class="panel">
<ul class="panel_head"><span>最新消息</span></ul>
<ul class="panel_body">
好兄弟的新书《深入理解Android 卷3》即将上市，感谢大家对《深入理解Android》系列书籍的支持。
</ul>
</div><div class="panel" id="panel_Search">
    <ul class="panel_head"><span>文章搜索</span></ul>
    <ul class="panel_body">
        <form id="frmSearch" action="http://so.csdn.net/search" class="form_search" target="_blank">
        <span><input id="inputSearch" type="text" class="blogsearch" title="请输入关键字"></span>
        <input id="btnSubmit" type="button" value="搜索" title="search in blog">
        <input type="hidden" name="q" id="inputQ">
        <input type="hidden" name="t" value="blog">
        <a id="btnSearchBlog" target="_blank"></a>
        </form>
    </ul>
</div>

<script type="text/javascript">
    $(function () {
        $("#btnSubmit").click(function () {           
            search();
        });

        $("#frmSearch").submit(function () {
            search();
            return false;
        });

        function search()
        {
            var url = "http://so.csdn.net/so/search/s.do?q=" + encodeURIComponent($("#inputSearch").val()) + "&u=" + username + "&t=blog";
            window.location.href = url;
        }   
    });
</script><div id="panel_Category" class="panel">
    <ul class="panel_head"><span>博客专栏</span></ul>
    <ul class="panel_body" id="sp_column">
    <table cellpadding="0" cellspacing="0"><tbody><tr>
    <td style="padding:10px 10px 0 0;">
    <a href="http://blog.csdn.net/column/details/innost.html" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/20151123174943677" style="width:75px;height:75px;"></a>
    </td>
    <td style="padding:10px 0; vertical-align:top;">
    <a href="http://blog.csdn.net/column/details/innost.html" target="_blank">深入理解Android</a>
    <p>文章：81篇</p>
    <span>阅读：1371360</span>
    </td>
    </tr></tbody></table>
    </ul>
</div><div id="panel_Archive" class="panel">
<ul class="panel_head"><span>文章存档</span></ul>
<ul class="panel_body">
<div id="archive_list"><li><a href="http://blog.csdn.net/Innost/article/month/2016/03">2016年03月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2016/01">2016年01月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2015/12">2015年12月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2015/10">2015年10月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2015/09">2015年09月</a><span>(1)</span></li><span class="hidelist" style="display:none;"><li><a href="http://blog.csdn.net/Innost/article/month/2015/08">2015年08月</a><span>(28)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2015/05">2015年05月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2015/03">2015年03月</a><span>(3)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2015/02">2015年02月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2015/01">2015年01月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2014/12">2014年12月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2014/10">2014年10月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2014/08">2014年08月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2014/05">2014年05月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2014/04">2014年04月</a><span>(2)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2014/03">2014年03月</a><span>(12)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2014/02">2014年02月</a><span>(3)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2013/12">2013年12月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2013/11">2013年11月</a><span>(2)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2013/08">2013年08月</a><span>(2)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2013/06">2013年06月</a><span>(2)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2013/05">2013年05月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2013/03">2013年03月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2013/01">2013年01月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2012/12">2012年12月</a><span>(3)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2012/11">2012年11月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2012/10">2012年10月</a><span>(2)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2012/09">2012年09月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2012/08">2012年08月</a><span>(4)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2012/07">2012年07月</a><span>(7)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2012/06">2012年06月</a><span>(3)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2012/05">2012年05月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2012/04">2012年04月</a><span>(2)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2012/03">2012年03月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2012/01">2012年01月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2011/12">2011年12月</a><span>(5)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2011/11">2011年11月</a><span>(6)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2011/10">2011年10月</a><span>(4)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2011/09">2011年09月</a><span>(4)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2011/08">2011年08月</a><span>(5)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2011/07">2011年07月</a><span>(2)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2011/02">2011年02月</a><span>(1)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2011/01">2011年01月</a><span>(6)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2010/12">2010年12月</a><span>(2)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2010/11">2010年11月</a><span>(3)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2010/07">2010年07月</a><span>(15)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2010/04">2010年04月</a><span>(6)</span></li><li><a href="http://blog.csdn.net/Innost/article/month/2009/03">2009年03月</a><span>(2)</span></li></span><div id="archive_list_button" class="list_closed">展开</div></div>
</ul>
</div>
<div id="hotarticls" class="panel">
<ul class="panel_head">
    <span>       
阅读排行    </span>
</ul>

<ul class="panel_body itemlist">
<li>
<a href="http://blog.csdn.net/innost/article/details/8474683" title="Android Wi-Fi Display（Miracast）介绍">Android Wi-Fi Display（Miracast）介绍</a><span>(104576)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/9008691" title="Android系统性能调优工具介绍">Android系统性能调优工具介绍</a><span>(65962)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/48228651" title="深入理解Android之Gradle">深入理解Android之Gradle</a><span>(61686)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/9187199" title="Android 4.2蓝牙介绍">Android 4.2蓝牙介绍</a><span>(50701)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/19299937" title="深入理解SELinux SEAndroid（第一部分）">深入理解SELinux SEAndroid（第一部分）</a><span>(50143)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/6172893" title="Android深入浅出之Surface[1]">Android深入浅出之Surface[1]</a><span>(48781)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/8272867" title="Android Project Butter分析">Android Project Butter分析</a><span>(45495)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/6055793" title="Android Looper和Handler分析">Android Looper和Handler分析</a><span>(43843)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/19641487" title="深入理解SELinux SEAndroid之二">深入理解SELinux SEAndroid之二</a><span>(36228)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/8876392" title="MTP in Android">MTP in Android</a><span>(35404)</span>
</li>
</ul>
</div>
<div id="homepageArticles" class="panel tracking-ad" data-mod="popu_4">
<ul class="panel_head"><span>推荐文章</span></ul>
<ul class="panel_body" id="ad_commend">
<ul>
<li><a href="http://blog.csdn.net/phodal/article/details/52145386" target="_blank">* 致JavaScript也将征服的物联网世界</a></li>
<li><a href="http://blog.csdn.net/ioio_jy/article/details/52124726" target="_blank">* 从苏宁电器到卡巴斯基：难忘的三年硕士时光</a></li>
<li><a href="http://blog.csdn.net/u013970991/article/details/52120005" target="_blank">* 作为一名基层管理者如何利用情商管理自己和团队（一）</a></li>
<li><a href="http://blog.csdn.net/zhangphil/article/details/52130212" target="_blank">* Android CircleImageView圆形ImageView</a></li>
<li><a href="http://blog.csdn.net/poem_qianmo/article/details/52144086" target="_blank">* 高质量代码的命名法则</a></li>


</ul></ul>
</div>


<div id="newcomments" class="panel">
<ul class="panel_head"><span>最新评论</span></ul>
<ul class="panel_body itemlist">
    <li>
   
         <a href="http://blog.csdn.net/innost/article/details/48228651#comments">深入理解Android之Gradle</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/eo_yohe" class="user_name">eo_yohe</a>:
mark
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/innost/article/details/6172893#comments">Android深入浅出之Surface[1]</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/liubin504" class="user_name">水淹大佛膝</a>:
看到头晕，没有一点逻辑性，很容易乱掉
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/innost/article/details/50377905#comments">深入理解Android之Java虚拟机Dalvik</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/wdong_love_cl" class="user_name">warmor</a>:
大牛，写的很详细。
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/innost/article/details/19299937#comments">深入理解SELinux SEAndroid（第一部分）</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/yangkaiqiang001" class="user_name">西漂大白杨</a>:
大赞
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/innost/article/details/19299937#comments">深入理解Android之Gradle</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/flyfight88" class="user_name">flyfight88</a>:
太厉害了，看了半天收获很多，另外有个问题想问博主，对于离线的服务器怎么下载classpath 'co...
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/innost/article/details/44519775#comments">深入理解Android之设备加密Device Encryption</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/u011022083" class="user_name">liucongvg</a>:
楼主你好，我想问一下用fastboot或flashtool刷完机之后，metadata里面是本身就有...
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/innost/article/details/44081147#comments">深入理解Android之Java Security第一部分</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/sohu_2011" class="user_name">sohu_2011</a>:
必须顶，精品
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/innost/article/details/49387395#comments">深入理解Android之AOP</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/kangaroo835127729" class="user_name">crazy__chen</a>:
写得太好了，看得我感动。目前公司Android项目里面也用aop打log，但是暂时没有想到其他应用。
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/innost/article/details/47207845#comments">[深入理解Android卷一全文-第四章]深入理解zygote</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/qq_16318981" class="user_name">文毫</a>:
这么好的文章
    </p>
    </li>
    <li>
   
         <a href="http://blog.csdn.net/innost/article/details/47207845#comments">深入理解Android之Gradle</a>
    <p style="margin:0px;"><a href="http://blog.csdn.net/nicks9999" class="user_name">nicks9999</a>:
//注意此处创建task的方法，是直接{}喔，那么它后面的tasks.withType(JavaCo...
    </p>
    </li>
</ul>
</div>
<div id="hotarticls2" class="panel">
<ul class="panel_head"><span>评论排行</span></ul>
<ul class="panel_body itemlist">
<li>
<a href="http://blog.csdn.net/innost/article/details/6124685" title="Android深入浅出之Binder机制">Android深入浅出之Binder机制</a><span>(120)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/48228651" title="深入理解Android之Gradle">深入理解Android之Gradle</a><span>(101)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/6172893" title="Android深入浅出之Surface[1]">Android深入浅出之Surface[1]</a><span>(98)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/6083467" title="Android MediaScanner 详尽分析">Android MediaScanner 详尽分析</a><span>(59)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/8474683" title="Android Wi-Fi Display（Miracast）介绍">Android Wi-Fi Display（Miracast）介绍</a><span>(58)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/7525205" title="深入理解卷II ---ICS源代码下载">深入理解卷II ---ICS源代码下载</a><span>(55)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/7648869" title="深入理解Android系列书籍的规划路线图">深入理解Android系列书籍的规划路线图</a><span>(55)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/6055793" title="Android Looper和Handler分析">Android Looper和Handler分析</a><span>(51)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/10184859" title="真诚邀请wifi专家审稿">真诚邀请wifi专家审稿</a><span>(47)</span>
</li>
<li>
<a href="http://blog.csdn.net/innost/article/details/14002899" title="Android 4.4代码资源115网盘下载！">Android 4.4代码资源115网盘下载！</a><span>(45)</span>
</li>
</ul>
</div>
    </div>
    <div class="clear">
    </div>
 </div>   
            <div class="clear">
            </div>
        </div>

        

<script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/cnick.js"></script>
<script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/newblog.min.js"></script>


<script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/showblogmedal.ashx"></script>
<script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/JavaScript1.js"></script><link rel="stylesheet" type="text/css" href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/pub_footer_2014.css"><div class="pub_fo"><div id="pub_footerall" class="pub_footer_new"><dl><dt></dt> <dd class="foot_sub_menu"><a href="http://www.csdn.net/company/about.html" target="_blank">公司简介</a><span>|</span><a href="http://www.csdn.net/company/recruit.html" target="_blank">招贤纳士</a><span>|</span><a href="http://www.csdn.net/company/marketing.html" target="_blank">广告服务</a><span>|</span><a href="http://www.csdn.net/company/account.html" target="_blank">银行汇款帐号</a><span>|</span><a href="http://www.csdn.net/company/contact.html" target="_blank">联系方式</a><span>|</span><a href="http://www.csdn.net/company/statement.html" target="_blank">版权声明</a><span>|</span><a href="http://www.csdn.net/company/layer.html" target="_blank">法律顾问</a><span>|</span><a href="mailto:webmaster@csdn.net">问题报告</a><span>|</span><a target="_blank" href="http://www.csdn.net/friendlink.html">合作伙伴</a><span>|</span><a href="http://bbs.csdn.net/forums/Service" target="_blank">论坛反馈</a></dd><dd class="foot_contact"><a href="javascript:void(0);" target="_blank" class="qq">网站客服</a><a href="http://wpa.qq.com/msgrd?v=3&amp;uin=2251809102&amp;site=qq&amp;menu=yes" target="_blank" class="qq">杂志客服</a><a href="http://e.weibo.com/csdnsupport/profile" target="_blank" class="weibo">微博客服</a><a href="mailto:webmaster@csdn.net" class="email" title="联系邮箱">webmaster@csdn.net</a><span class="phone" title="服务热线">400-600-2320</span><span class="interval">|</span><span>北京创新乐知信息技术有限公司 版权所有</span><span class="interval">|</span><span>江苏乐知网络技术有限公司 提供商务支持</span></dd><dd class="foot_copyright"><span>京&nbsp;ICP&nbsp;证&nbsp;09002463&nbsp;号</span><span class="interval">|</span><span>Copyright © 1999-2014, CSDN.NET, All Rights Reserved&nbsp;</span><a href="http://www.hd315.gov.cn/beian/view.asp?bianhao=010202001032100010" target="_blank"><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/gongshang_logos.gif" alt="GongshangLogo" title=""></a></dd></dl></div></div><div id="note1" class="csdn_note" style="display:none; position:absolute; z-index:9999; width:440px">  <span class="notice_top_arrow"><span class="inner"></span></span>  <div class="box"></div></div><div class="csdn_notice_tip" style="display:none; position:absolute; z-index:9990; width:170px">  <iframe src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/saved_resource(2).html" frameborder="0" scrolling="no" style="z-index:-1;position:absolute;top:0;left:0;width:100%;height:100%;background:transparent"></iframe>  <div class="tip_text">您有<strong>0</strong>条新通知</div>  <a href="javascript:void 0" class="close2"></a></div><script id="noticeScript" type="text/javascript" btnid="header_notice_num" wrapid="note1" count="5" subcount="5" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/notify.js"></script>

    <script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/login.js"></script>
<script type="text/javascript">document.write("<img src=http://counter.csdn.net/pv.aspx?id=24 border=0 width=0 height=0>");</script><img src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/pv.aspx" border="0" width="0" height="0">
<script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/counter.js"></script><script type="text/javascript" charset="UTF-8" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/msg.popup.js"></script>
<script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/ad-blog.js"></script>
<script type="text/javascript">
    $(function () {
        function __get_code_toolbar(snippet_id) {
            return $("<span class='tracking-ad' data-mod='popu_167'><a href='https://code.csdn.net/snippets/"
                    + snippet_id
                    + "' target='_blank' title='在CODE上查看代码片'  style='text-indent:0;'><img src='https://code.csdn.net/assets/CODE_ico.png' width=12 height=12 alt='在CODE上查看代码片' style='position:relative;top:1px;left:2px;'/></a></span>"
                    + "<span class='tracking-ad' data-mod='popu_170'><a href='https://code.csdn.net/snippets/"
                    + snippet_id
                    + "/fork' target='_blank' title='派生到我的代码片' style='text-indent:0;'><img src='https://code.csdn.net/assets/ico_fork.svg' width=12 height=12 alt='派生到我的代码片' style='position:relative;top:2px;left:2px;'/></a></span>");
        }
        
        $("[code_snippet_id]").each(function () {
            __s_id = $(this).attr("code_snippet_id");
            if (__s_id != null && __s_id != "" && __s_id != 0 && parseInt(__s_id) > 70020) {
                __code_tool = __get_code_toolbar(__s_id);
                $(this).prev().find(".tools").append(__code_tool);
            }
        });

        $(".bar").show();
    });
</script>




    </div><input type="hidden" id="aa_g_data_ids">
      <!--new top-->
    
    <script id="csdn-toolbar-id" btnid="header_notice_num" wrapid="note1" count="5" subcount="5" type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/toolbar.js"></script>
     <!--new top-->
   
    <link href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/ask_float_block.css" type="text/css" rel="stylesheet">
    <script language="JavaScript" type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/wmd.js"></script>
    <script language="JavaScript" type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/showdown.js"></script>
    <script language="JavaScript" type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/prettify.js"></script>
    <script language="JavaScript" type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/ask_float_block.js"></script>
   

  <div id="a52b5334d" style="width: 1px; height: 1px; display: none;">
                    <script id="adJs52b5334" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/52b5334.js"></script>
                    <script>document.getElementById("adJs52b5334").src = "http://ads.csdn.net/js/opt/52b5334.js?t=" + Math.random();</script>
   </div>

    <link rel="stylesheet" href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/blog_code.css">
    <script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/saveToCode.js"></script>
      <script type="text/javascript" src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/main(1).js"></script>

   
 <div id="tag-suggest-pop">
  <div class="relative">
    <div class="close"></div>
    <div class="content"></div>
  </div>
</div><link rel="stylesheet" type="text/css" media="screen" href="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/ask_float_fonts_css-6b30a53970eb5c3a2a045e3df585b475.css"><div data-mod="popu_64" class="csdn-tracking-statistics" chg-blk="0"><a id="com-quick-reply" title="快速回复" style="top:329px"></a><a id="com-d-top-a" style="top: 367px; display: inline;" title="返回顶部" onclick=""></a> </div><div class="pop_edit ask_second comm_ask_second"><h3>提问</h3><span class="ask_float_span">您的问题将会被发布在“<a class="ask_float_channel" href="http://ask.csdn.net/" target="_blank" style="cursor:pointer">技术问答</a>”频道</span><a href="http://blog.csdn.net/innost/article/details/48228651#" nodetype="close" class="close">×</a><div class="context"><div class="err_div"><span class="err_ico"></span><span class="err_txt">该问题已存在，请勿重复提问</span></div><div class="input_div"><input id="askInputSecond" type="text" style="font-size:14px;" placeholder="问题标题"></div><div class="cm_box"><div class="cm_dialog"></div> <div class="pop_cm cm_add_link"><input type="text" placeholder="链接内容" id="af_cm_link_txt"><input type="text" placeholder="链接地址" id="af_cm_link_url"><input type="text" placeholder="链接提示" id="af_cm_link_tit"><div class="text-right"><span class="btn btn-default btn-sm" id="add_link_btn">插入链接</span> </div> </div><div class="pop_cm cm_add_img"><div class="nav-tabs"><a class="img_tab active" href="http://blog.csdn.net/innost/article/details/48228651#tab_upload">本地上传</a><a class="img_tab" href="http://blog.csdn.net/innost/article/details/48228651#tab_weburl">网络图片</a></div><div class="tab_panel active" id="tab_upload"><div class="set_img"><iframe src="./深入理解Android之Gradle - Innost的专栏 - 博客频道 - CSDN.NET_files/upload.html"></iframe></div></div><div class="tab_panel" id="tab_weburl"><input type="text" placeholder="图片地址" id="af_cm_img_url"><input type="text" placeholder="图片说明" id="af_cm_img_alt"><div class="text-right"><span class="btn btn-default btn-sm" id="add_img_btn">插入图片</span> </div></div> </div></div> <textarea id="editor_all" rows="8" style="display: none;"></textarea><div class="editor-toolbar"><i class="separator">|</i><a class="icon-headline" title="标题一（Ctrl+Alt+1）"></a><a class="icon-heading" title="标题二（Ctrl+Alt+2）"></a><a class="icon-bold" title="粗体（Ctrl+B）"></a><a class="icon-italic" title="斜体（Ctrl+I）"></a><i class="separator">|</i><a class="icon-quote-left" title="引用（Ctrl+’）"></a><a class="icon-code" title="插入代码片（Ctrl+,）"></a><a class="icon-list-ul" title="无序列表（Ctrl+L）"></a><a class="icon-list-ol" title="有序列表（Ctrl+Alt+L）"></a><i class="separator">|</i><a class="icon-link" title="添加链接（Ctrl+K）"></a><a class="icon-picture" title="添加图片（Ctrl+Alt+I）"></a><i class="separator">|</i><a class="icon-reply" title="撤退（Ctrl+Z）"></a><a class="icon-share-alt" title="前进（Ctrl+Shift+Z）"></a><i class="separator">|</i><a class="icon-info" href="http://ask.csdn.net/pages/markdown" target="_blank" title="markdown语法参考"></a><a class="icon-preview" title="预览"></a><i class="separator">|</i></div><div class="CodeMirror cm-s-paper CodeMirror-focused"><div style="overflow: hidden; position: relative; width: 3px; height: 0px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" style="position: absolute; padding: 0px; width: 1000px; height: 1em; outline: none; font-size: 4px;" tabindex="0"></textarea></div><div class="CodeMirror-hscrollbar"><div style="height: 1px;"></div></div><div class="CodeMirror-vscrollbar"><div style="width: 1px;"></div></div><div class="CodeMirror-scrollbar-filler"></div><div class="CodeMirror-gutter-filler"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="min-width: 33px;"><div style="position: relative;"><div class="CodeMirror-lines"><div style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre>&nbsp;<span style="display: inline-block; width: 1px; margin-right: -1px;">&nbsp;</span></pre></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code"></div><div class="CodeMirror-cursor" style="visibility: hidden;">&nbsp;</div><div class="CodeMirror-cursor CodeMirror-secondarycursor" style="visibility: hidden;">&nbsp;</div></div></div></div></div><div style="position: absolute; height: 30px; width: 1px;"></div><div class="CodeMirror-gutters" style="display: none;"></div></div></div><div class="editor-statusbar"><span class="lines">0</span><span class="words">0</span><span class="cursor">0:0</span></div><div class="div_tags clearfix"><div id="divSearchTags" class="tags_con"><input type="text"></div><input type="hidden" name="txtSearchTags"></div><div id="ask2_tagRecomm_div" class="drt_tagRecomm tracking-ad" data-mod="popu_73"><span class="drt_tit">推荐标签：</span></div></div><div class="success"><div class="left_area"><input id="chk_cb" type="checkbox"><span class="wyxs">我要悬赏</span><input id="cb_num" class="cb_num" readonly="true"><span class="phib_rii"><span> 币</span></span></div><a href="http://blog.csdn.net/innost/article/details/48228651#" nodetype="cancel" class="cancel">取消</a><a href="http://blog.csdn.net/innost/article/details/48228651#" nodetype="ok" class="ok">发布</a></div></div><div id="common_ask_div_sc" class="searchContainer"><div class="sTitle">可能存在类似的问题：</div><div class="sFooter"><a class="sFirstNewAsk">我想提一个新问题</a></div></div><div id="mask_code"></div><div class="gist_edit"><div class="save_snippets clearfix"><div class="tit"><h3>保存代码片</h3><span>整理和分享保存的代码片，请访问<a href="https://code.csdn.net/snippets_manage" target="_blank">代码笔记</a></span></div><div class="con_form"><ul class="gist_edit_list clearfix"><li><span class="red">*</span><span class="txt">标题</span><input id="form_title" class="form-input" placeholder="深入理解Android之Gradle" type="text"></li><li><span class="red">*</span><span class="txt">描述</span><textarea id="form-textarea" class="form-textarea" placeholder="深入理解Android之Gradle： http://blog.csdn.net/innost/article/details/48228651"></textarea></li><li><span class="red">&nbsp;</span><span class="txt">标签</span><div id="divSearchTags"><input id="insertTag" class="insertTag" placeholder="请输入标签，按Enter生成(最多5项)" type="text" value="" name="insertTag" maxlength="21" style="color: rgb(51, 51, 51);"><input id="OrganTag" class="OrganTag" type="hidden" name="OrganTag" value=""><input id="OldOrganTag" class="OldOrganTag" type="hidden" name="OldOrganTag" value=""><input type="hidden" name="txtSearchTags"></div></li></ul></div><div class="bottom-bar"><a href="javascript:;" class="btn-submit btn-cancel">取消</a><span class="tracking-ad" data-mod="popu_250"><a class="btn-submit btn-confirm" href="javascript:;" target="_blank">确定</a></span></div></div></div></body></html>